<commit_before>var http = require('http');
var https = require('https');
var FormData = require('form-data');

module.exports = MailgunProvider;

/**
 * Creates an instance of the Mailgun email provider.
 *
 * @constructor
 * @this {MailgunProvider}
 * @param {string} domain The Mailgun-registered domain to send email from.
 * @param {string} apiKey API Key for the Mailgun account holding the domain.
 * @param {object} [options] Additional optional configuration.
 * @param {boolean} [options.testMode=false] See: {@link http://documentation.mailgun.com/user_manual.html#sending-in-test-mode}
 * @param {boolean} [options.apiSecure=true] API connection protocol - true = HTTPS, false = HTTP
 * @param {string} [options.apiHostname=api.mailgun.net] Hostname for the API connection
 * @param {number} [options.apiPort] Port for the API connection - defaults to match the protocol (HTTPS-443, HTTP-80)
 */
function MailgunProvider(domain, apiKey, options) {
	if (typeof domain !== 'string'
		|| typeof apiKey !== 'string') {
		throw new Error('Invalid parameters');
	}

	options = options || {};

	if (typeof options.testMode === 'undefined')
		options.testMode = true;

	if (typeof options.apiSecure === 'undefined')
		options.apiSecure = true;

	options.apiHostname = options.apiHostname || 'api.mailgun.net';
	options.apiPort = options.apiPort || (options.apiSecure ? 443 : 80);

	this.domain = domain;
	this.apiKey = apiKey;
	this.options = options;
}

/**
 * Indicates the outcome of a mail-sending attempt.
 * @callback MailgunProvider~onResult
 * @param {error} [error] A non-null value indicates failure.
 */

/**
 * Attempts to send the message through the Mailgun API.
 *
 * @this {MailgunProvider}
 * @param {Message} message The message to send.
 * @param {MailgunProvider~onResult} [callback] Notified when the attempt fails or succeeds.
 */
MailgunProvider.prototype.mail = function (message, callback) {
	var form;

	// this can fail if the message is invalid
	try {
		form = this._formForMessage(message);
	} catch (error) {
		if (callback)
			callback(error);

		return;
	}

	var options = {
		hostname: this.options.apiHostname,
		port: this.options.apiPort,
		path: '/v2/' + this.domain + '/messages',
		method: 'POST',
		auth: 'api:' + this.apiKey,
		headers: form.getHeaders()
	};

	var protocol = this.options.apiSecure ? https : http;

	var request = protocol.request(options);

	form.pipe(request);
	request.end();

	// if no callback, the outcome doesn't matter
	if (!callback)
		return;

	request.on('error', function (error) {
		callback(error);
	});

	request.on('response', function (response) {
		if (response.statusCode == 200) {
			callback();
			response.socket.end();
			return;
		}

		var body = '';

		response.on('data', function (chunk) {
			body += chunk;
		});

		response.on('end', function (chunk) {
			var error = new Error('Email could not be sent');

			error.httpStatusCode = response.statusCode;
			error.httpResponseData = body;

			callback(error);
		});
	});
}

MailgunProvider.prototype._formForMessage = function (message) {
	message = message || {};
	message.to = message.to || [];
	message.cc = message.cc || [];
	message.bcc = message.bcc || [];

	// mailgun will return a 400 error if these are missing
	if (!message.from.length
		|| !message.to.length
		|| !message.subject
		|| (!message.textBody && !message.htmlBody)) {
		throw new Error('Invalid parameters');
	}

	var form = new FormData();

	form.append('from', message.from);
	form.append('to', message.to.join(','));
	form.append('subject', message.subject);

	if (message.replyto)
		form.append('h:Reply-To', message.replyto);

	if (message.cc.length)
		form.append('cc', message.cc.join(','));

	if (message.bcc.length)
		form.append('bcc', message.bcc.join(','));

	if (message.textBody)
		form.append('text', message.textBody);

	if (message.htmlBody)
		form.append('html', message.htmlBody);

	form.append('o:testmode', this.options.testMode ? 'true' : 'false');

	// todo: attachment support

	return form;
}
<commit_msg>Fixed message field presence check<commit_after>var http = require('http');
var https = require('https');
var FormData = require('form-data');

module.exports = MailgunProvider;

/**
 * Creates an instance of the Mailgun email provider.
 *
 * @constructor
 * @this {MailgunProvider}
 * @param {string} domain The Mailgun-registered domain to send email from.
 * @param {string} apiKey API Key for the Mailgun account holding the domain.
 * @param {object} [options] Additional optional configuration.
 * @param {boolean} [options.testMode=false] See: {@link http://documentation.mailgun.com/user_manual.html#sending-in-test-mode}
 * @param {boolean} [options.apiSecure=true] API connection protocol - true = HTTPS, false = HTTP
 * @param {string} [options.apiHostname=api.mailgun.net] Hostname for the API connection
 * @param {number} [options.apiPort] Port for the API connection - defaults to match the protocol (HTTPS-443, HTTP-80)
 */
function MailgunProvider(domain, apiKey, options) {
	if (typeof domain !== 'string'
		|| typeof apiKey !== 'string') {
		throw new Error('Invalid parameters');
	}

	options = options || {};

	if (typeof options.testMode === 'undefined')
		options.testMode = true;

	if (typeof options.apiSecure === 'undefined')
		options.apiSecure = true;

	options.apiHostname = options.apiHostname || 'api.mailgun.net';
	options.apiPort = options.apiPort || (options.apiSecure ? 443 : 80);

	this.domain = domain;
	this.apiKey = apiKey;
	this.options = options;
}

/**
 * Indicates the outcome of a mail-sending attempt.
 * @callback MailgunProvider~onResult
 * @param {error} [error] A non-null value indicates failure.
 */

/**
 * Attempts to send the message through the Mailgun API.
 *
 * @this {MailgunProvider}
 * @param {Message} message The message to send.
 * @param {MailgunProvider~onResult} [callback] Notified when the attempt fails or succeeds.
 */
MailgunProvider.prototype.mail = function (message, callback) {
	var form;

	// this can fail if the message is invalid
	try {
		form = this._formForMessage(message);
	} catch (error) {
		if (callback)
			callback(error);

		return;
	}

	var options = {
		hostname: this.options.apiHostname,
		port: this.options.apiPort,
		path: '/v2/' + this.domain + '/messages',
		method: 'POST',
		auth: 'api:' + this.apiKey,
		headers: form.getHeaders()
	};

	var protocol = this.options.apiSecure ? https : http;

	var request = protocol.request(options);

	form.pipe(request);
	request.end();

	// if no callback, the outcome doesn't matter
	if (!callback)
		return;

	request.on('error', function (error) {
		callback(error);
	});

	request.on('response', function (response) {
		if (response.statusCode == 200) {
			callback();
			response.socket.end();
			return;
		}

		var body = '';

		response.on('data', function (chunk) {
			body += chunk;
		});

		response.on('end', function (chunk) {
			var error = new Error('Email could not be sent');

			error.httpStatusCode = response.statusCode;
			error.httpResponseData = body;

			callback(error);
		});
	});
}

MailgunProvider.prototype._formForMessage = function (message) {
	message = message || {};
	message.to = message.to || [];
	message.cc = message.cc || [];
	message.bcc = message.bcc || [];

	// mailgun will return a 400 error if these are missing
	if (!message.from
		|| !message.to.length
		|| !message.subject
		|| (!message.textBody && !message.htmlBody)) {
		throw new Error('Invalid parameters');
	}

	var form = new FormData();

	form.append('from', message.from);
	form.append('to', message.to.join(','));
	form.append('subject', message.subject);

	if (message.replyto)
		form.append('h:Reply-To', message.replyto);

	if (message.cc.length)
		form.append('cc', message.cc.join(','));

	if (message.bcc.length)
		form.append('bcc', message.bcc.join(','));

	if (message.textBody)
		form.append('text', message.textBody);

	if (message.htmlBody)
		form.append('html', message.htmlBody);

	form.append('o:testmode', this.options.testMode ? 'true' : 'false');

	// todo: attachment support

	return form;
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors

frappe.has_indicator = function(doctype) {
	// returns true if indicator is present
	if(frappe.model.is_submittable(doctype)) {
		return true;
	} else if((frappe.listview_settings[doctype] || {}).get_indicator
		|| frappe.workflow.get_state_fieldname(doctype)) {
		return true;
	} else if(frappe.meta.has_field(doctype, 'enabled')
		|| frappe.meta.has_field(doctype, 'disabled')) {
		return true;
	}
	return false;
}

frappe.get_indicator = function(doc, doctype) {
	if(doc.__unsaved) {
		return [__("Not Saved"), "orange"];
	}

	if(!doctype) doctype = doc.doctype;

	var workflow = frappe.workflow.workflows[doctype];
	var without_workflow = workflow ? workflow['override_status'] : true;

	var settings = frappe.listview_settings[doctype] || {};

	var is_submittable = frappe.model.is_submittable(doctype),
		workflow_fieldname = frappe.workflow.get_state_fieldname(doctype);

	// workflow
	if(workflow_fieldname && !without_workflow) {
		var value = doc[workflow_fieldname];
		if(value) {
			var colour = "";

			if(locals["Workflow State"][value] && locals["Workflow State"][value].style) {
				var colour = {
					"Success": "green",
					"Warning": "orange",
					"Danger": "red",
					"Primary": "blue",
				}[locals["Workflow State"][value].style];
			}
			if(!colour) colour = "darkgrey";

			return [__(value), colour, workflow_fieldname + ',=,' + value];
		}
	}

	// draft if document is submittable
	if(is_submittable && doc.docstatus==0 && !settings.has_indicator_for_draft) {
		return [__("Draft"), "red", "docstatus,=,0"];
	}

	// cancelled
	if(is_submittable && doc.docstatus==2 && !settings.has_indicator_for_cancelled) {
		return [__("Cancelled"), "red", "docstatus,=,2"];
	}

	if(settings.get_indicator) {
		var indicator = settings.get_indicator(doc);
		if(indicator) return indicator;
	}

	// if submittable
	if(is_submittable && doc.docstatus==1) {
		return [__("Submitted"), "blue", "docstatus,=,1"];
	}

	// based on status
	if(doc.status) {
		return [__(doc.status), frappe.utils.guess_colour(doc.status)];
	}

	// based on enabled
	if(frappe.meta.has_field(doctype, 'enabled')) {
		if(doc.enabled) {
			return [__('Enabled'), 'blue', 'enabled,=,1'];
		} else {
			return [__('Disabled'), 'grey', 'enabled,=,0'];
		}
	}

	// based on disabled
	if(frappe.meta.has_field(doctype, 'disabled')) {
		if(doc.disabled) {
			return [__('Disabled'), 'grey', 'disabled,=,1'];
		} else {
			return [__('Enabled'), 'blue', 'disabled,=,0'];
		}
	}
}
<commit_msg>fix: colours missing from indicator.js (bp #10631) (#10805)<commit_after>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors

frappe.has_indicator = function(doctype) {
	// returns true if indicator is present
	if(frappe.model.is_submittable(doctype)) {
		return true;
	} else if((frappe.listview_settings[doctype] || {}).get_indicator
		|| frappe.workflow.get_state_fieldname(doctype)) {
		return true;
	} else if(frappe.meta.has_field(doctype, 'enabled')
		|| frappe.meta.has_field(doctype, 'disabled')) {
		return true;
	}
	return false;
}

frappe.get_indicator = function(doc, doctype) {
	if(doc.__unsaved) {
		return [__("Not Saved"), "orange"];
	}

	if(!doctype) doctype = doc.doctype;

	var workflow = frappe.workflow.workflows[doctype];
	var without_workflow = workflow ? workflow['override_status'] : true;

	var settings = frappe.listview_settings[doctype] || {};

	var is_submittable = frappe.model.is_submittable(doctype),
		workflow_fieldname = frappe.workflow.get_state_fieldname(doctype);

	// workflow
	if(workflow_fieldname && !without_workflow) {
		var value = doc[workflow_fieldname];
		if(value) {
			var colour = "";

			if(locals["Workflow State"][value] && locals["Workflow State"][value].style) {
				var colour = {
					"Success": "green",
					"Warning": "orange",
					"Danger": "red",
					"Primary": "blue",
					"Inverse": "black",
					"Info": "light-blue",
				}[locals["Workflow State"][value].style];
			}
			if(!colour) colour = "darkgrey";

			return [__(value), colour, workflow_fieldname + ',=,' + value];
		}
	}

	// draft if document is submittable
	if(is_submittable && doc.docstatus==0 && !settings.has_indicator_for_draft) {
		return [__("Draft"), "red", "docstatus,=,0"];
	}

	// cancelled
	if(is_submittable && doc.docstatus==2 && !settings.has_indicator_for_cancelled) {
		return [__("Cancelled"), "red", "docstatus,=,2"];
	}

	if(settings.get_indicator) {
		var indicator = settings.get_indicator(doc);
		if(indicator) return indicator;
	}

	// if submittable
	if(is_submittable && doc.docstatus==1) {
		return [__("Submitted"), "blue", "docstatus,=,1"];
	}

	// based on status
	if(doc.status) {
		return [__(doc.status), frappe.utils.guess_colour(doc.status)];
	}

	// based on enabled
	if(frappe.meta.has_field(doctype, 'enabled')) {
		if(doc.enabled) {
			return [__('Enabled'), 'blue', 'enabled,=,1'];
		} else {
			return [__('Disabled'), 'grey', 'enabled,=,0'];
		}
	}

	// based on disabled
	if(frappe.meta.has_field(doctype, 'disabled')) {
		if(doc.disabled) {
			return [__('Disabled'), 'grey', 'disabled,=,1'];
		} else {
			return [__('Enabled'), 'blue', 'disabled,=,0'];
		}
	}
}
<|endoftext|>


<commit_before>/** articles */
const express = require('express')
const router = express.Router()
const fs = require('fs');
const path = require('path')
const db_articles = require(path.resolve(__dirname, '../data/articles.db.js'))
const zmq = require('zeromq')
const pull = zmq.socket('pull')
pull.connect('tcp://localhost:8001')

var _preview_list = []
var _articles = []

refresh()

pull.on('message', (msg) => {
  msg = JSON.parse(msg)
  if (msg.event == 'refresh')
  {
    console.log('刷新文章列表')
    refresh()
  }
})

router.get('/', (req, res) => {
    res.send({list: _preview_list})
})

router.get('/:id', (req, res) => {
  let id = req.params.id
  let article = _articles.find(ele => ele.ref == id)
  if (article)
    return res.send({content :article.content})
  res.status(404).end()
})

function genPreviewList (docs) {
  return docs.map(ele => {
    return {
      title: ele.title,
      summary: ele.summary,
      ref: ele.ref
    }
  })
}

function refresh() {
  db_articles.find({}, (err, docs) => {
    if (err)
      return console.log(err)
    if (!docs)
      return console.log('no articles yet')
    _articles = docs
    _preview_list = genPreviewList(docs)
  })
}

module.exports = router
<commit_msg>新文章在老文章上方<commit_after>/** articles */
const express = require('express')
const router = express.Router()
const fs = require('fs');
const path = require('path')
const db_articles = require(path.resolve(__dirname, '../data/articles.db.js'))
const zmq = require('zeromq')
const pull = zmq.socket('pull')
pull.connect('tcp://localhost:8001')

var _preview_list = []
var _articles = []

refresh()

pull.on('message', (msg) => {
  msg = JSON.parse(msg)
  if (msg.event == 'refresh')
  {
    console.log('刷新文章列表')
    refresh()
  }
})

router.get('/', (req, res) => {
    res.send({list: _preview_list.reverse()})
})

router.get('/:id', (req, res) => {
  let id = req.params.id
  let article = _articles.find(ele => ele.ref == id)
  if (article)
    return res.send({content :article.content})
  res.status(404).end()
})

function genPreviewList (docs) {
  return docs.map(ele => {
    return {
      title: ele.title,
      summary: ele.summary,
      ref: ele.ref
    }
  })
}

function refresh() {
  db_articles.find({}, (err, docs) => {
    if (err)
      return console.log(err)
    if (!docs)
      return console.log('no articles yet')
    _articles = docs
    _preview_list = genPreviewList(docs)
  })
}

module.exports = router
<|endoftext|>


<commit_before>const {Venue} = require('../utils/mongo/models');
const Foursquare = require('./foursquare/Foursquare');

const storeVenue = function* (venueData) {
  const venue = new Venue(venueData);
  if (!venue.tasks) venue.tasks = [];
  yield venue.save();
  return venue;
};

const getVenueFromExternalSource = function* (id, source, fields) {
  let venue;
  let query;
  if (source === 'foursquare') {
    console.log("GET venue from foursquareID with fields ", fields);
    query = Venue.findOne({foursquareId: id});
    if (fields) query.select(fields);
    venue = yield query.exec();
    if (!venue) {
      console.log('venue from foursquare');
      const venueData = yield Foursquare.getVenueById(id);

      console.log('storing it');
      venue = yield storeVenue(venueData);
      console.log(venue);
    }
  } else {
    throw new Error(`Unknow source ${source}`);
  }
  return venue;
};

const getVenue = function* (id, source, fields) {
  let venue;
  let query;
  if (!source) {
    query = Venue.findOne({_id: id});
    if (fields) {
      query.select(fields);
    }
    venue = yield query.exec();
  } else {
    venue = yield getVenueFromExternalSource(id, source, fields);
  }
  return venue;
};

const getVenuesWithinRadiusWithTasks = function* (center, radius, fields) {
  const radiusInRad = (radius / 1000) / 6378.1;
  if (!Array.isArray(center)) {
    if ((center.lat && center.lng) || (center.latitude && center.longitude)) {
      center = [center.lng, center.lat];
    } else {
      throw new Error(`Invalid parameters center. it should be an array [lng, lat] or an object {lat, lng} but got ${JSON.stringify(center)}`);
    }
  }
  const query = Venue.find({
    $and: [
      {
        'address.location': {
          $geoWithin: {
            $centerSphere: [center, radiusInRad],
          },
        },
      },
      {
        tasks: {
          $not: {
            $size: 0,
          },
        },
      },
      {
        'tasks.nbAnswers': 0,
      },
    ],
  }).sort({_id: -1});
  if (fields) {
    query.select(fields);
  }
  const venues = yield query.exec();
  /*
  if (!fields || fields.nbOpenTasks) {
    venues = putNbOpenTasksForVenues(venues);
  }
  */
  return venues;
};

const searchVenue = function* ({lat, lng}, query, radius) {
  const venues = yield Foursquare.searchVenue({lat, lng}, query, radius);
  return venues;
};

const getVenuePicture = function(venue, size) {
  const defaultImg = 'http://www.eltis.org/sites/eltis/files/default_images/photo_default_4.png';
  if (!venue) return defaultImg;
  if (!venue.pictures) return defaultImg;
  if (venue.pictures.url) return venue.pictures.url;
  if (!venue.pictures.prefix || !venue.pictures.suffix) return defaultImg;
  const sizeParam = (size) ? `${size.width}x${size.height}` : 'original';
  return `${venue.pictures.prefix}${sizeParam}${venue.pictures.suffix}`;
};

const getVenuePictureUrlFromVenueId = function* (venueId, size) {
  const venue = yield getVenue(venueId);
  return getVenuePicture(venue, size);
};

const getNbOpenTask = function* (venue) {
  console.log(venue);
  if (venue.tasks &&
    venue.tasks.length === venue.tasks.filter(t => (t.nbAnswers !== undefined)).length) {
    return venue.tasks.filter(task => !task.nbAnswers).length;
  }
  const result = yield Venue.aggregate([
    {
      $match: {
        _id: venue._id,
      },
    },
    {
      $unwind: '$tasks',
    },
    {
      $match: {
        'tasks.nbAnswers': 0,
      },
    },
    {
      $group: {
        _id: '$_id',
        count: {
          $sum: 1,
        },
      },
    },
  ]).exec();

  return result.length === 0 ? 0 : result[0].count;
};

const reduce = function(venue) {
  return {
    _id: venue._id,
    source: venue.source,
    name: venue.name,
    foursquareId: venue.id || venue.foursquareId,
    address: {
      location: venue.address.location,
    },
    nbTasks: (venue.tasks) ? venue.tasks.length : 0,
  };
};

module.exports = {
  getVenue,
  getVenuesWithinRadiusWithTasks,
  searchVenue,
  getVenuePicture,
  getVenuePictureUrlFromVenueId,
  getNbOpenTask,
  reduce,
};
<commit_msg>Clean code [skip ci]<commit_after>const {Venue} = require('../utils/mongo/models');
const Foursquare = require('./foursquare/Foursquare');

const storeVenue = function* (venueData) {
  const venue = new Venue(venueData);
  if (!venue.tasks) venue.tasks = [];
  yield venue.save();
  return venue;
};

const getVenueFromExternalSource = function* (id, source, fields) {
  let venue;
  let query;
  if (source === 'foursquare') {
    console.log('GET venue from foursquareID with fields ', fields);
    query = Venue.findOne({foursquareId: id});
    if (fields) query.select(fields);
    venue = yield query.exec();
    if (!venue) {
      console.log('venue from foursquare');
      const venueData = yield Foursquare.getVenueById(id);

      console.log('storing it');
      venue = yield storeVenue(venueData);
      console.log(venue);
    }
  } else {
    throw new Error(`Unknow source ${source}`);
  }
  return venue;
};

const getVenue = function* (id, source, fields) {
  let venue;
  let query;
  if (!source) {
    query = Venue.findOne({_id: id});
    if (fields) {
      query.select(fields);
    }
    venue = yield query.exec();
  } else {
    venue = yield getVenueFromExternalSource(id, source, fields);
  }
  return venue;
};

const getVenuesWithinRadiusWithTasks = function* (center, radius, fields) {
  const radiusInRad = (radius / 1000) / 6378.1;
  if (!Array.isArray(center)) {
    if ((center.lat && center.lng) || (center.latitude && center.longitude)) {
      center = [center.lng, center.lat];
    } else {
      throw new Error(`Invalid parameters center. it should be an array [lng, lat] or an object {lat, lng} but got ${JSON.stringify(center)}`);
    }
  }
  const query = Venue.find({
    $and: [
      {
        'address.location': {
          $geoWithin: {
            $centerSphere: [center, radiusInRad],
          },
        },
      },
      {
        tasks: {
          $not: {
            $size: 0,
          },
        },
      },
      {
        'tasks.nbAnswers': 0,
      },
    ],
  }).sort({_id: -1});
  if (fields) {
    query.select(fields);
  }
  const venues = yield query.exec();
  return venues;
};

const searchVenue = function* ({lat, lng}, query, radius) {
  const venues = yield Foursquare.searchVenue({lat, lng}, query, radius);
  return venues;
};

const getVenuePicture = function(venue, size) {
  const defaultImg = 'http://www.eltis.org/sites/eltis/files/default_images/photo_default_4.png';
  if (!venue) return defaultImg;
  if (!venue.pictures) return defaultImg;
  if (venue.pictures.url) return venue.pictures.url;
  if (!venue.pictures.prefix || !venue.pictures.suffix) return defaultImg;
  const sizeParam = (size) ? `${size.width}x${size.height}` : 'original';
  return `${venue.pictures.prefix}${sizeParam}${venue.pictures.suffix}`;
};

const getVenuePictureUrlFromVenueId = function* (venueId, size) {
  const venue = yield getVenue(venueId);
  return getVenuePicture(venue, size);
};

const getNbOpenTask = function* (venue) {
  console.log(venue);
  if (venue.tasks &&
    venue.tasks.length === venue.tasks.filter(t => (t.nbAnswers !== undefined)).length) {
    return venue.tasks.filter(task => !task.nbAnswers).length;
  }
  const result = yield Venue.aggregate([
    {
      $match: {
        _id: venue._id,
      },
    },
    {
      $unwind: '$tasks',
    },
    {
      $match: {
        'tasks.nbAnswers': 0,
      },
    },
    {
      $group: {
        _id: '$_id',
        count: {
          $sum: 1,
        },
      },
    },
  ]).exec();

  return result.length === 0 ? 0 : result[0].count;
};

const reduce = function(venue) {
  return {
    _id: venue._id,
    source: venue.source,
    name: venue.name,
    foursquareId: venue.id || venue.foursquareId,
    address: {
      location: venue.address.location,
    },
    nbTasks: (venue.tasks) ? venue.tasks.length : 0,
  };
};

module.exports = {
  getVenue,
  getVenuesWithinRadiusWithTasks,
  searchVenue,
  getVenuePicture,
  getVenuePictureUrlFromVenueId,
  getNbOpenTask,
  reduce,
};
<|endoftext|>


<commit_before>var pg = require('pg');

function insertTemp(temp) {
  pg.connect(process.env.DATABASE_URL, function(err, client, done) {
    if(handleError(err)){
      console.log("error i pg connection");
      return;
    }

    client.query('INSERT INTO temperature (date_measured, temp)' +
      'VALUES ($1,$2) RETURNING id', [new Date(), temp],
      function(err, result) {
        if (err) {
          console.log(err)
        } else {
          console.log("Insert temperature with id: " + result.rows[0].id)
        }
      });
      done();
  });
}

function getTemp(response) {
  console.log("get Temp i repo kallt");
  pg.connect(process.env.DATABASE_URL, function(err, client, done) {
        if(handleError(err,client)) {
            console.log("error i pg connection");
            return;
        }

        var query = client.query('SELECT date_measured, temp FROM temperature');
        var rows = [];

        query.on('row', function(row, result) {
            result.addRow(row);
          });

        query.on('end', function(result) {
            response.send(result.rows);
          });
          done();
        });
      }

  function handleError(err, client) {
    // no error occurred, continue with the request
     if(!err) return false;

     // An error occurred, remove the client from the connection pool.
     // A truthy value passed to done will remove the connection from the pool
     // instead of simply returning it to be reused.
     // In this case, if we have successfully received a client (truthy)
     // then it will be removed from the pool.
     if(client){
       done(client);
     }
     res.writeHead(500, {'content-type': 'text/plain'});
     res.end('An error occurred');
     return true;
  }
      module.exports.insertTemp = insertTemp;
      module.exports.getTemp = getTemp;
<commit_msg>Fix error in HandleError<commit_after>var pg = require('pg');

function insertTemp(temp) {
  pg.connect(process.env.DATABASE_URL, function(err, client, done) {
    if(err){
      console.log("error i pg connection");
      done();
      return;
    }

    client.query('INSERT INTO temperature (date_measured, temp)' +
      'VALUES ($1,$2) RETURNING id', [new Date(), temp],
      function(err, result) {
        if (err) {
          console.log(err)
        } else {
          console.log("Insert temperature with id: " + result.rows[0].id)
        }
      });
      done();
  });
}

function getTemp(response) {
  console.log("get Temp i repo kallt");
  pg.connect(process.env.DATABASE_URL, function(err, client, done) {
        if(err) {
            console.log("error i pg connection");
            done()
            return;
        }

        var query = client.query('SELECT date_measured, temp FROM temperature');
        var rows = [];

        query.on('row', function(row, result) {
            result.addRow(row);
          });

        query.on('end', function(result) {
            response.send(result.rows);
          });
          done();
        });
      }

      module.exports.insertTemp = insertTemp;
      module.exports.getTemp = getTemp;
<|endoftext|>


<commit_before>var log = require('../util/logger'),
    _ = require('lodash'),
    converter = require('../url/converter'),
    events = {
        'default': [],
        'internal.response.headers': []
    },
    URL = require('url'),
    http = require('http'),
    https = require('https');

httpAgent = new http.Agent();
httpAgent.maxSockets = 20;
httpsAgent = new https.Agent();
httpsAgent.maxSockets = 20;

var proxy = module.exports = function(route, endpoint) {
    route = route || '/';

    var to = URL.parse(endpoint),
        request = to.protocol === 'https:' ? https.request : http.request,
        agent = to.protocol === 'https:' ? httpsAgent : httpAgent;

    return function(req, res, next) {
        var opts = converter.convert(req.route || route, req.url, to.href);

        opts.method = req.method;
        opts.headers = to.headers ? _.extend(req.headers, to.headers) : req.headers;
        // make sure we use our agent
        opts.agent = agent;

        events['default'].forEach(function(interceptor) {
            interceptor(req, res, opts);
        });

        var end = res.end;

        req.on('error', function(err) {
            log.error('External request error:', err.message);
            next(err);
        });

        res.on('error', function(err) {
            log.error('External response error:', err.message);
            next(err);
        });

        res.end = function() {
            log.verbose.http(req, res, opts.href + ' (' + req.url + ')');
            return end.apply(this, arguments);
        };

        var myReq = request(opts, function(myRes) {
            events['internal.response.headers'].forEach(function(interceptor) {
                interceptor(myRes.headers);
            });

            res.writeHead(myRes.statusCode, myRes.headers);

            myRes.on('error', function(err) {
                log.error('Internal response error:', err.message);
                next(err);
            });

            myRes.pipe(res);
        });

        var mySocket;

        myReq.on('socket', function(socket) {
            mySocket = socket;

            socket.setNoDelay(true);
            socket.setTimeout(0);
            socket.setKeepAlive(true);
        });

        myReq.on('error', function(err) {
            if (err.code === 'ECONNRESET') {
                // Treat this like a close even if less than graceful...
            } else {
                log.error('Internal request error:', err.message);
                next(err);
            }
        });

        myReq.on('end', function() {
            mySocket.unref();
        });

        if (!req.readable) {
            myReq.end();
        } else {
            req.pipe(myReq);

            req.on('end', function() {
                myReq.end();
            });
        }
    };
};

proxy.setMaxSockets = function(maxSockets) {
    httpAgent.maxSockets = httpsAgent.maxSockets = maxSockets;
};

proxy.addInterceptor = function(cb, event) {
    event = event || 'default';

    var callbacks = events[event];

    if (!callbacks) {
        callbacks = events[event] = [];
    }

    callbacks.push(cb);
};
<commit_msg>Add req, res to interceptor.<commit_after>var log = require('../util/logger'),
    _ = require('lodash'),
    converter = require('../url/converter'),
    events = {
        'default': [],
        'internal.response.headers': []
    },
    URL = require('url'),
    http = require('http'),
    https = require('https');

httpAgent = new http.Agent();
httpAgent.maxSockets = 20;
httpsAgent = new https.Agent();
httpsAgent.maxSockets = 20;

var proxy = module.exports = function(route, endpoint) {
    route = route || '/';

    var to = URL.parse(endpoint),
        request = to.protocol === 'https:' ? https.request : http.request,
        agent = to.protocol === 'https:' ? httpsAgent : httpAgent;

    return function(req, res, next) {
        var opts = converter.convert(req.route || route, req.url, to.href);

        opts.method = req.method;
        opts.headers = to.headers ? _.extend(req.headers, to.headers) : req.headers;
        // make sure we use our agent
        opts.agent = agent;

        events['default'].forEach(function(interceptor) {
            interceptor(req, res, opts);
        });

        var end = res.end;

        req.on('error', function(err) {
            log.error('External request error:', err.message);
            next(err);
        });

        res.on('error', function(err) {
            log.error('External response error:', err.message);
            next(err);
        });

        res.end = function() {
            log.verbose.http(req, res, opts.href + ' (' + req.url + ')');
            return end.apply(this, arguments);
        };

        var myReq = request(opts, function(myRes) {
            events['internal.response.headers'].forEach(function(interceptor) {
                interceptor(req, res, myRes.headers);
            });

            res.writeHead(myRes.statusCode, myRes.headers);

            myRes.on('error', function(err) {
                log.error('Internal response error:', err.message);
                next(err);
            });

            myRes.pipe(res);
        });

        var mySocket;

        myReq.on('socket', function(socket) {
            mySocket = socket;

            socket.setNoDelay(true);
            socket.setTimeout(0);
            socket.setKeepAlive(true);
        });

        myReq.on('error', function(err) {
            if (err.code === 'ECONNRESET') {
                // Treat this like a close even if less than graceful...
            } else {
                log.error('Internal request error:', err.message);
                next(err);
            }
        });

        myReq.on('end', function() {
            mySocket.unref();
        });

        if (!req.readable) {
            myReq.end();
        } else {
            req.pipe(myReq);

            req.on('end', function() {
                myReq.end();
            });
        }
    };
};

proxy.setMaxSockets = function(maxSockets) {
    httpAgent.maxSockets = httpsAgent.maxSockets = maxSockets;
};

proxy.addInterceptor = function(cb, event) {
    event = event || 'default';

    var callbacks = events[event];

    if (!callbacks) {
        callbacks = events[event] = [];
    }

    callbacks.push(cb);
};
<|endoftext|>


<commit_before>exports = module.exports = JSONMiddleware;

var Q = require('q');
var mime = require('mime');

function JSONMiddleware() {

}

JSONMiddleware.prototype.parseConnection = function(connection, controller) {
	var defer = Q.defer();

	//application/json;charset=UTF-8
	var contentType = connection.request.headers['content-type'];
	if(contentType && mime.extension(contentType) == 'json') {
		var body = '';

		//todo: is there some kind of limit? we do not want to parse excessive amounts of data
		//perhaps this is a job for a reverse proxy in production
		//todo: move this to a separate middleware as it's likely this will be needed by other middlewares
		connection.request.on('data', function(chunk) {
			body += chunk;
		})
		connection.request.on('end', function() {
			if(body) {
				//todo: do we want to catch invalid JSON?
				controller.body = JSON.parse(body);
			}

			defer.resolve();
		});
	}
	else {
		defer.resolve();
	}

	return defer.promise;
}<commit_msg>implemented json middleware to return selected keys only<commit_after>exports = module.exports = JSONMiddleware;

var Q = require('q');
var mime = require('mime');

function JSONMiddleware() {

}

JSONMiddleware.prototype.parseConnection = function(connection, controller) {
	var defer = Q.defer();

	//application/json;charset=UTF-8
	var contentType = connection.request.headers['content-type'];
	if(contentType && mime.extension(contentType) == 'json') {
		var body = '';

		//todo: is there some kind of limit? we do not want to parse excessive amounts of data
		//perhaps this is a job for a reverse proxy in production
		//todo: move this to a separate middleware as it's likely this will be needed by other middlewares
		connection.request.on('data', function(chunk) {
			body += chunk;
		})
		connection.request.on('end', function() {
			if(body) {
				try {
					controller.body = JSON.parse(body);
				}
				catch(e) {
					controller.body = {};

					// TODO: we really need some kind of logging -- this shouldn't happen unnoticed in development mode at least
				}

				controller.json = function(keys) {
					var json = {};
					keys.forEach(function(key) {
						if(typeof controller.body[key] != 'undefined') {
							json[key] = controller.body[key];
						}
					})
					return json;
				};
			}

			defer.resolve();
		});
	}
	else {
		defer.resolve();
	}

	return defer.promise;
}<|endoftext|>


<commit_before>'use strict';

var mik_loan = require('../lib/mik-loan.js');

/*
  ======== A Handy Little Nodeunit Reference ========
  https://github.com/caolan/nodeunit

  Test methods:
    test.expect(numAssertions)
    test.done()
  Test assertions:
    test.ok(value, [message])
    test.equal(actual, expected, [message])
    test.notEqual(actual, expected, [message])
    test.deepEqual(actual, expected, [message])
    test.notDeepEqual(actual, expected, [message])
    test.strictEqual(actual, expected, [message])
    test.notStrictEqual(actual, expected, [message])
    test.throws(block, [error], [message])
    test.doesNotThrow(block, [error], [message])
    test.ifError(value)
*/

exports['awesome'] = {
  setUp: function(done) {
    // setup here
    done();
  },
  'no args': function(test) {
    test.expect(1);
    // tests here
    test.equal(mik_loan.awesome(), 'awesome', 'should be awesome.');
    test.done();
  },
};
<commit_msg>First test added<commit_after>'use strict';

var loan_server = require('../lib/loan-server.js');

/*
  ======== A Handy Little Nodeunit Reference ========
  https://github.com/caolan/nodeunit

  Test methods:
    test.expect(numAssertions)
    test.done()
  Test assertions:
    test.ok(value, [message])
    test.equal(actual, expected, [message])
    test.notEqual(actual, expected, [message])
    test.deepEqual(actual, expected, [message])
    test.notDeepEqual(actual, expected, [message])
    test.strictEqual(actual, expected, [message])
    test.notStrictEqual(actual, expected, [message])
    test.throws(block, [error], [message])
    test.doesNotThrow(block, [error], [message])
    test.ifError(value)
*/

exports['awesome'] = {
    setUp: function(done) {
	// setup here
	done();
    },
    'no args': function(test) {
	test.expect(1);
	// tests here
	var server = loan_server.start();
	console.log(server);
	test.equal(server(), 'awesome', 'should be awesome.');
	test.done();
    },
};
<|endoftext|>


<commit_before>import jwt from 'jsonwebtoken';
import config from '../../../config/config';
import User from '../models/user.model';

const debug = true;
var clients = {}; //eslint-disable-line
const socketConnection = (io) => {
  io.on('connection', (client) => {

    client.on('authenticate', async (data) => {
      try {
        const decoded = jwt.verify(data.token, config.jwtSecret);
        if (decoded !== undefined) {
          client.authenticated = true; // eslint-disable-line
          // join user to a room according to his unique id
          client.join(decoded.id);
          clients[decoded.id] = client;
          client.id = decoded.id;
          // mark user as online
          const user = await User.get(decoded.id);
          user.online = true;
          await user.save();
          console.log(io);
          client.emit('authenticated', { auth: true });
        } else {
          client.emit('authenticated', { auth: false });
        }
      } catch (err) {
        client.emit('authenticated', { auth: false });
        client.authenticated = false; // eslint-disable-line
        client.disconnect(); // force disconnect not authorized client
      }
    });
    client.on('disconnect', async () => {
      try {
        const user = await User.get(client.id);
        user.online = false;
        await user.save();
        client.disconnect();
      } catch (e) {
        client.authenticated = false; // eslint-disable-line
        client.disconnect();
      }
    });
  });
  return io;
};

const socketEmitter = (io) => {
  const object = {
    sendToUser(follower, post) {
      io.on('connection', (client) => {
        console.log('sendingg', follower._id);
        io.emit('update_feed', post);
      });
    }
  };
  return object;
};

export { socketConnection, socketEmitter };
<commit_msg>remove double connection<commit_after>import jwt from 'jsonwebtoken';
import config from '../../../config/config';
import User from '../models/user.model';

const debug = true;
var clients = {}; //eslint-disable-line
const socketConnection = (io) => {
  io.on('connection', (client) => {

    client.on('authenticate', async (data) => {
      try {
        const decoded = jwt.verify(data.token, config.jwtSecret);
        if (decoded !== undefined) {
          client.authenticated = true; // eslint-disable-line
          // join user to a room according to his unique id
          client.join(decoded.id);
          clients[decoded.id] = client;
          client.id = decoded.id;
          // mark user as online
          const user = await User.get(decoded.id);
          user.online = true;
          await user.save();
          client.emit('authenticated', { auth: true });
        } else {
          client.emit('authenticated', { auth: false });
        }
      } catch (err) {
        client.emit('authenticated', { auth: false });
        client.authenticated = false; // eslint-disable-line
        client.disconnect(); // force disconnect not authorized client
      }
    });
    client.on('disconnect', async () => {
      try {
        const user = await User.get(client.id);
        user.online = false;
        await user.save();
        client.disconnect();
      } catch (e) {
        client.authenticated = false; // eslint-disable-line
        client.disconnect();
      }
    });
  });
  return io;
};

const socketEmitter = (io) => {
  const object = {
    sendToUser(follower, post) {

      console.log('sendingg', follower._id);
      io.to(follower._id).emit('update_feed', post);

    }
  };
  return object;
};

export { socketConnection, socketEmitter };
<|endoftext|>


<commit_before>import jwt from 'jsonwebtoken';
import config from '../../../config/config';
import User from '../models/user.model';

const debug = true;
const socketConnection = (io) => {
  io.on('connection', (client) => {
    client.on('authenticate', async (data) => {
      try {
        const decoded = jwt.verify(data.token, config.jwtSecret);
        if (decoded !== undefined) {
          client.authenticated = true; // eslint-disable-line
          // join user to a room according to his unique id
          client.join(decoded.id);
          client.id = decoded.id; // eslint-disable-line
          // mark user as online
          const user = await User.get(decoded.id);
          user.online = true;
          await user.save();
          client.emit('authenticated', { auth: true });
        } else {
          client.emit('authenticated', { auth: false });
        }
      } catch (err) {
        client.emit('authenticated', { auth: false });
        client.authenticated = false; // eslint-disable-line
        client.disconnect(); // force disconnect not authorized client
      }
    });
    client.on('disconnect', async () => {
      try {
        const user = await User.get(client.id);
        user.online = false;
        await user.save();
        client.disconnect();
      } catch (e) {
        client.authenticated = false; // eslint-disable-line
        client.disconnect();
      }
    });
  });
};

const socketEmitter = (io) => {
  const object = {
    sendToUser(follower, post) {
      console.log('follower', follower);
      console.log('send data', post);
      io.to(follower._id).emit('update_feed', post);
    }
  };
  return object;
};

export { socketConnection, socketEmitter };
<commit_msg>test follower id<commit_after>import jwt from 'jsonwebtoken';
import config from '../../../config/config';
import User from '../models/user.model';

const debug = true;
const socketConnection = (io) => {
  io.on('connection', (client) => {
    client.on('authenticate', async (data) => {
      try {
        const decoded = jwt.verify(data.token, config.jwtSecret);
        if (decoded !== undefined) {
          client.authenticated = true; // eslint-disable-line
          // join user to a room according to his unique id
          client.join(decoded.id);
          client.id = decoded.id; // eslint-disable-line
          // mark user as online
          const user = await User.get(decoded.id);
          user.online = true;
          await user.save();
          client.emit('authenticated', { auth: true });
        } else {
          client.emit('authenticated', { auth: false });
        }
      } catch (err) {
        client.emit('authenticated', { auth: false });
        client.authenticated = false; // eslint-disable-line
        client.disconnect(); // force disconnect not authorized client
      }
    });
    client.on('disconnect', async () => {
      try {
        const user = await User.get(client.id);
        user.online = false;
        await user.save();
        client.disconnect();
      } catch (e) {
        client.authenticated = false; // eslint-disable-line
        client.disconnect();
      }
    });
  });
};

const socketEmitter = (io) => {
  const object = {
    sendToUser(follower, post) {
      console.log('follower', follower._id);
      console.log('send data', post);
      io.to(follower._id).emit('update_feed', post);
    }
  };
  return object;
};

export { socketConnection, socketEmitter };
<|endoftext|>


<commit_before>/**
 * extends BaseModel with ACL functionality.
 */
var _ = require('lodash');
var BaseModel = require('./base_model');
var _debug = require('debug');
var logId = 'serverbone:models:acl';
var acl = require('../acl');
var debug = {
  trace: _debug(logId + ':trace'),
  log: _debug(logId + ':log'),
  warn: _debug(logId + ':warn'),
  error: _debug(logId + ':error')
};

var ACLModel = BaseModel.extend({
  initialize: function (args, options) {
    ACLModel.__super__.initialize.apply(this, arguments);
    options = options || {};
    this._processPermissions();
    this.addRoles(options.roles);
    if (options.actor) {
      this.actor = options.actor;
    }
  },

  save: function(key, val, options) {
    var opts = options || {};
    if (key == null || typeof key === 'object') {
      opts = val || {};
    }
    opts.action = opts.action || this.isNew() ? 'create' : 'update';
    opts.actor = opts.actor || this.actor;
    return ACLModel.__super__.save.call(this, key, opts);
  },

  fetch: function(options) {
    options = options || {};
    options.action = options.action || 'read';
    options.actor = options.actor || this.actor;
    return ACLModel.__super__.fetch.call(this, options);
  },

  destroy: function(options) {
    options =  options || {};
    options.action = options.action || 'destroy';
    options.actor = options.actor || this.actor;
    return ACLModel.__super__.destroy.call(this, options);
  },
  /**
   * Add role/roles to this instance
   *
   * @param  {Object|Array} roles
   */
  addRoles: function(roles) {
    this.roles = this.roles || [];
    if (!roles) return;
    if (!_.isArray(roles)) roles = [roles];
    debug.log('Adding roles %s to model %s',_.uniq(this.roles.concat(roles)), this.url());
    this.roles = _.uniq(this.roles.concat(roles));
  },

  /**
   * Return any matching roles for model from this model.
   *
   * @param  {Object} actor
   * @return {Array}
   */
  getRoles: function(actor) {
    //debug.log('Model %s asking roles from %s',actor ? actor.url() : '', this.url());
    var roles = [];
    if (!actor) return roles;
    _.each(this.relationDefinitions, function (value, key) {
      var refs = _.pairs(value.references)[0];
      if (!value.references || !value.Class) return;

      if (actor instanceof value.Class && actor.has(refs[0]) && this.has(refs[1]) &&
        actor.get(refs[0]) === this.get(refs[1])) {

        roles = roles.concat(value.roles || key);
      }
    }, this);
    roles = _.uniq((actor.roles || []).concat(roles));
    return roles;
  },

  _processPermissions: function () {
    var permissions = {};
    if (this.schema && this.schema.permissions) {
      permissions = this.schema.permissions;
    }
    this.acl = new acl.ACL(permissions);
  },

  toJSON: function (options) {
    debug.log('toJSON: %s',JSON.stringify(options));
    options = options || {};
    var json = ACLModel.__super__.toJSON.apply(this, arguments);
    if (!options.actor && options.user) {
      options.actor = options.user;
    }
    if (options.actor && this.acl) {
      var readableFields = this.propertiesWithAccess('read', options.actor);
      _.each(Object.keys(json), function (key) {
        if (readableFields.indexOf(key) === -1) delete json[key];
      });
    }
    return json;
  },

  // check access to this model
  canAccess: function (action, model) {
    debug.trace('canAccess %s', action);
    if (!this.acl) return true;
    if (!model) {
      debug.log('using default access model');
      model = new ACLModel();
    }
    debug.log('canAccess %s %s', action, model.url());
    return this.acl.assert(this.getRoles(model), action);
  },
  // Field level access: get properties which user has permissions
  // field can override object level access mask
  propertiesWithAccess: function (action, model) {
    if (!model) {
      debug.log('using default access model');
      model = new ACLModel();
    }
     debug.trace('propertiesWithAccess to action %s with model %s',action,model.toJSON());
    var objectAccess = this.canAccess(action, model);
    var keys = [];
    var self = this;
    if (!this.schema || !this.schema.properties) return keys;

    _.each(this.schema.properties, function (prop, key) {
      if (!prop.permissions && objectAccess) {
        keys.push(key);
      } else if (prop.permissions) {
        var mask = new acl.ACL(prop.permissions);
        var roles = self.getRoles(model);
        if (mask.assert(roles, action)) {
          debug.log('adding key %s because of %s',key,roles.join(','));
          keys.push(key);
        }
      }
    }, this);
    debug.log('propertiesWithAccess giving out keys: %s', keys.join(','));
    return keys;
  },

  validate: function (attrs, options) {
    debug.trace('validate: %s',JSON.stringify(options));
    var changedAttrs = this.changedAttributes();
    options = options ? _.clone(options) : {};
    debug.trace('validate: %s',JSON.stringify(options));
    var action = options.action || (this.isNew() ? 'create' : 'update');
    var actor = options.actor || options.user || options.model;

    var noAccessTo, canAccess;
    if (this.acl) {
      canAccess = this.canAccess(action, actor);
      debug.log('we have an acl, canAccess: %s',canAccess);
      if (canAccess && changedAttrs) {
        var changedProps = Object.keys(changedAttrs);
        var canActProps = this.propertiesWithAccess(action, actor);
        noAccessTo = _.difference(changedProps, canActProps);
      }
      if ((!canAccess && changedAttrs) || (noAccessTo && noAccessTo.length > 0)) {
        debug.log('Failing validation, no access with action %s to %s',action, JSON.stringify(noAccessTo));
        var error = new Error('No access to ' + action + ' fields:' + noAccessTo);
        if (options && options.error) {
          options.error(this, error);
        }
      }
    }
    ACLModel.__super__.validate.apply(this, arguments);
  }
});

module.exports = ACLModel;<commit_msg>use this.actor if none passed<commit_after>/**
 * extends BaseModel with ACL functionality.
 */
var _ = require('lodash');
var BaseModel = require('./base_model');
var _debug = require('debug');
var logId = 'serverbone:models:acl';
var acl = require('../acl');
var debug = {
  trace: _debug(logId + ':trace'),
  log: _debug(logId + ':log'),
  warn: _debug(logId + ':warn'),
  error: _debug(logId + ':error')
};

var ACLModel = BaseModel.extend({
  initialize: function (args, options) {
    ACLModel.__super__.initialize.apply(this, arguments);
    options = options || {};
    this._processPermissions();
    this.addRoles(options.roles);
    if (options.actor) {
      this.actor = options.actor;
    }
  },

  save: function(key, val, options) {
    var opts = options || {};
    if (key == null || typeof key === 'object') {
      opts = val || {};
    }
    opts.action = opts.action || this.isNew() ? 'create' : 'update';
    opts.actor = opts.actor || this.actor;
    return ACLModel.__super__.save.call(this, key, opts);
  },

  fetch: function(options) {
    options = options || {};
    options.action = options.action || 'read';
    options.actor = options.actor || this.actor;
    return ACLModel.__super__.fetch.call(this, options);
  },

  destroy: function(options) {
    options =  options || {};
    options.action = options.action || 'destroy';
    options.actor = options.actor || this.actor;
    return ACLModel.__super__.destroy.call(this, options);
  },
  /**
   * Add role/roles to this instance
   *
   * @param  {Object|Array} roles
   */
  addRoles: function(roles) {
    this.roles = this.roles || [];
    if (!roles) return;
    if (!_.isArray(roles)) roles = [roles];
    debug.log('Adding roles %s to model %s',_.uniq(this.roles.concat(roles)), this.url());
    this.roles = _.uniq(this.roles.concat(roles));
  },

  /**
   * Return any matching roles for model from this model.
   *
   * @param  {Object} actor
   * @return {Array}
   */
  getRoles: function(actor) {
    //debug.log('Model %s asking roles from %s',actor ? actor.url() : '', this.url());
    var roles = [];
    if (!actor) return roles;
    _.each(this.relationDefinitions, function (value, key) {
      var refs = _.pairs(value.references)[0];
      if (!value.references || !value.Class) return;

      if (actor instanceof value.Class && actor.has(refs[0]) && this.has(refs[1]) &&
        actor.get(refs[0]) === this.get(refs[1])) {

        roles = roles.concat(value.roles || key);
      }
    }, this);
    roles = _.uniq((actor.roles || []).concat(roles));
    return roles;
  },

  _processPermissions: function () {
    var permissions = {};
    if (this.schema && this.schema.permissions) {
      permissions = this.schema.permissions;
    }
    this.acl = new acl.ACL(permissions);
  },

  toJSON: function (options) {
    debug.log('toJSON: %s',JSON.stringify(options));
    options = options || {};
    var json = ACLModel.__super__.toJSON.apply(this, arguments);
    if (!options.actor && options.user) {
      options.actor = options.user || this.actor;
    }
    if (options.actor && this.acl) {
      var readableFields = this.propertiesWithAccess('read', options.actor);
      _.each(Object.keys(json), function (key) {
        if (readableFields.indexOf(key) === -1) delete json[key];
      });
    }
    return json;
  },

  // check access to this model
  canAccess: function (action, model) {
    debug.trace('canAccess %s', action);
    if (!this.acl) return true;
    if (!model) {
      debug.log('using default access model');
      model = new ACLModel();
    }
    debug.log('canAccess %s %s', action, model.url());
    return this.acl.assert(this.getRoles(model), action);
  },
  // Field level access: get properties which user has permissions
  // field can override object level access mask
  propertiesWithAccess: function (action, model) {
    if (!model) {
      debug.log('using default access model');
      model = new ACLModel();
    }
     debug.trace('propertiesWithAccess to action %s with model %s',action,model.toJSON());
    var objectAccess = this.canAccess(action, model);
    var keys = [];
    var self = this;
    if (!this.schema || !this.schema.properties) return keys;

    _.each(this.schema.properties, function (prop, key) {
      if (!prop.permissions && objectAccess) {
        keys.push(key);
      } else if (prop.permissions) {
        var mask = new acl.ACL(prop.permissions);
        var roles = self.getRoles(model);
        if (mask.assert(roles, action)) {
          debug.log('adding key %s because of %s for mask %s',key,roles.join(','), JSON.stringify(mask));
          keys.push(key);
        }
      }
    }, this);
    debug.log('propertiesWithAccess giving out keys: %s', keys.join(','));
    return keys;
  },

  validate: function (attrs, options) {
    debug.trace('validate: %s',JSON.stringify(options));
    var changedAttrs = this.changedAttributes();
    options = options ? _.clone(options) : {};
    debug.trace('validate: %s',JSON.stringify(options));
    var action = options.action || (this.isNew() ? 'create' : 'update');
    var actor = options.actor || options.user || options.model || this.actor;

    var noAccessTo, canAccess, changedProps, canActProps;
    if (this.acl) {
      canAccess = this.canAccess(action, actor);
      debug.log('we have an acl, canAccess: %s',canAccess);
      if (canAccess && changedAttrs) {
        changedProps = Object.keys(changedAttrs);
        canActProps = this.propertiesWithAccess(action, actor);
      //  console.log(canActProps, changedProps);
        noAccessTo = _.difference(changedProps, canActProps);
      }
      if ((!canAccess && changedAttrs) || (noAccessTo && noAccessTo.length > 0)) {
       // console.log( noAccessTo, canAccess,changedAttrs, changedProps, canActProps, actor);
        debug.log('Failing validation, no access with action %s to %s',action, JSON.stringify(noAccessTo));
        var error = new Error('No access to ' + action + ' fields:' + noAccessTo);
        if (options && options.error) {
          options.error(this, error);
        }
      }
    }
    //ACLModel.__super__.validate.apply(this, arguments);
  }
});

module.exports = ACLModel;<|endoftext|>


<commit_before>import { module } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { click, render, settled, waitFor } from '@ember/test-helpers';
import { test, testRequiringTransitions } from '../../helpers/bootstrap';
import hbs from 'htmlbars-inline-precompile';
import setupNoDeprecations from '../../helpers/setup-no-deprecations';
import a11yAudit from 'ember-a11y-testing/test-support/audit';
import sinon from 'sinon';

module('Integration | Component | bs-alert', function (hooks) {
  setupRenderingTest(hooks);
  setupNoDeprecations(hooks);

  hooks.beforeEach(function () {
    this.actions = {};
    this.send = (actionName, ...args) => this.actions[actionName].apply(this, args);
  });

  test('alert has correct CSS classes', async function (assert) {
    await render(hbs`<BsAlert @type="success" @dismissible={{true}}>Test</BsAlert>`);

    assert.dom('.alert').exists('alert has alert class');
    assert.dom('.alert').hasClass('alert-success', 'alert has type class');
    assert.dom('.alert').hasClass('alert-dismissible', 'alert has dismissible class');
  });

  test('dismissible alert can be hidden by clicking close button with fade=false', async function (assert) {
    await render(hbs`<BsAlert @type="success" @fade={{false}}>Test</BsAlert>`);

    assert.dom('button.close').exists({ count: 1 }, 'alert has close button');
    await click('button.close');

    assert.dom('.alert').doesNotExist('alert has no alert class');
    assert.dom('*').hasText('', 'alert has no content');
  });

  testRequiringTransitions('dismissible alert can be hidden by clicking close button with fade=true', async function (
    assert
  ) {
    await render(hbs`<BsAlert @type="success" @fade={{true}}>Test</BsAlert>`);

    assert.dom('button.close').exists({ count: 1 }, 'alert has close button');
    let promise = click('button.close');
    await waitFor('.alert:not(.in)');

    assert.dom('.alert').exists('alert has alert class');
    assert.dom('.alert').hasNoClass('in', 'alert has no in class');

    await promise;
    assert.dom('.alert').doesNotExist('alert has no alert class');
    assert.dom('*').hasText('', 'alert has no content');
  });

  test('alert can be hidden by setting visible property', async function (assert) {
    this.set('visible', true);
    await render(hbs`<BsAlert @type="success" @fade={{false}} @visible={{visible}}>Test</BsAlert>`);

    this.set('visible', false);

    assert.dom('.alert').doesNotExist('alert has no alert class');
    assert.dom('*').hasText('', 'alert has no content');
  });

  test('onDismiss is called when clicking the close button', async function (assert) {
    let action = sinon.spy();
    this.actions.dismiss = action;
    await render(hbs`<BsAlert @type="success" @fade={{false}} @onDismiss={{action "dismiss"}}>Test</BsAlert>`);
    await click('button.close');
    assert.ok(action.calledOnce, 'onDismiss has been called.');
  });

  test('alert is not hidden after clicking the close button when onDismiss action return false', async function (assert) {
    let action = sinon.stub();
    action.returns(false);
    this.actions.dismiss = action;
    await render(hbs`<BsAlert @type="success" @fade={{false}} @onDismiss={{action "dismiss"}}>Test</BsAlert>`);
    await click('button.close');
    assert.ok(action.calledOnce, 'onDismiss has been called.');

    assert.dom('.alert').exists('alert is still visible');
  });

  test('onDismissed is called after modal is closed', async function (assert) {
    let action = sinon.spy();
    this.actions.dismissed = action;
    await render(hbs`<BsAlert @type="success" @fade={{false}} @onDismissed={{action "dismissed"}}>Test</BsAlert>`);
    await click('button.close');
    assert.ok(action.calledOnce, 'onDismissed has been called.');
  });

  test('When fade is true, onDismissed is called once when visible changes from true to false', async function (assert) {
    let action = sinon.spy();
    this.dismissed = action;
    this.isAlertShown = true;

    await render(
      hbs`<BsAlert @fade={{true}} @onDismissed={{this.dismissed}} @visible={{this.isAlertShown}}>Test</BsAlert>`
    );

    this.set('isAlertShown', false);
    await settled();

    assert.ok(action.calledOnce, 'onDismissed is called once.');
  });

  test('When fade is false, onDismissed is called once when visible changes from true to false', async function (assert) {
    let action = sinon.spy();
    this.dismissed = action;
    this.isAlertShown = true;

    await render(
      hbs`<BsAlert @fade={{false}} @onDismissed={{this.dismissed}} @visible={{this.isAlertShown}}>Test</BsAlert>`
    );

    this.set('isAlertShown', false);
    await settled();

    assert.ok(action.calledOnce, 'onDismissed is called once.');
  });

  test('alert is initially hidden when visible=false', async function (assert) {
    await render(hbs`<BsAlert @type="success" @fade={{false}} @visible={{false}}>Test</BsAlert>`);

    assert.dom('.alert').doesNotExist('alert has no alert class');
    assert.dom('*').hasText('', 'alert has no content');
  });

  test('alert can be made visible when setting visible=true', async function (assert) {
    this.set('visible', false);
    await render(hbs`<BsAlert @type="success" @visible={{visible}} @fade={{false}}>Test</BsAlert>`);
    this.set('visible', true);

    assert.dom('.alert').exists('alert has alert class');
    assert.dom('.alert').hasClass('alert-success', 'alert has type class');
  });

  test('dismissing alert does not change public visible property (DDAU)', async function (assert) {
    this.set('visible', true);
    await render(hbs`<BsAlert @type="success" @visible={{visible}} @fade={{false}}>Test</BsAlert>`);

    await click('button.close');

    assert.equal(this.visible, true, 'Does not modify visible property');
  });

  test('it passes accessibility checks', async function (assert) {
    await render(hbs`<BsAlert @type="success">Test</BsAlert>`);

    await a11yAudit();
    assert.ok(true, 'A11y audit passed');
  });
});
<commit_msg>Added a test case for onDismissed when the value of visible remains the same<commit_after>import { module } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { click, render, settled, waitFor } from '@ember/test-helpers';
import { test, testRequiringTransitions } from '../../helpers/bootstrap';
import hbs from 'htmlbars-inline-precompile';
import setupNoDeprecations from '../../helpers/setup-no-deprecations';
import a11yAudit from 'ember-a11y-testing/test-support/audit';
import sinon from 'sinon';

module('Integration | Component | bs-alert', function (hooks) {
  setupRenderingTest(hooks);
  setupNoDeprecations(hooks);

  hooks.beforeEach(function () {
    this.actions = {};
    this.send = (actionName, ...args) => this.actions[actionName].apply(this, args);
  });

  test('alert has correct CSS classes', async function (assert) {
    await render(hbs`<BsAlert @type="success" @dismissible={{true}}>Test</BsAlert>`);

    assert.dom('.alert').exists('alert has alert class');
    assert.dom('.alert').hasClass('alert-success', 'alert has type class');
    assert.dom('.alert').hasClass('alert-dismissible', 'alert has dismissible class');
  });

  test('dismissible alert can be hidden by clicking close button with fade=false', async function (assert) {
    await render(hbs`<BsAlert @type="success" @fade={{false}}>Test</BsAlert>`);

    assert.dom('button.close').exists({ count: 1 }, 'alert has close button');
    await click('button.close');

    assert.dom('.alert').doesNotExist('alert has no alert class');
    assert.dom('*').hasText('', 'alert has no content');
  });

  testRequiringTransitions('dismissible alert can be hidden by clicking close button with fade=true', async function (
    assert
  ) {
    await render(hbs`<BsAlert @type="success" @fade={{true}}>Test</BsAlert>`);

    assert.dom('button.close').exists({ count: 1 }, 'alert has close button');
    let promise = click('button.close');
    await waitFor('.alert:not(.in)');

    assert.dom('.alert').exists('alert has alert class');
    assert.dom('.alert').hasNoClass('in', 'alert has no in class');

    await promise;
    assert.dom('.alert').doesNotExist('alert has no alert class');
    assert.dom('*').hasText('', 'alert has no content');
  });

  test('alert can be hidden by setting visible property', async function (assert) {
    this.set('visible', true);
    await render(hbs`<BsAlert @type="success" @fade={{false}} @visible={{visible}}>Test</BsAlert>`);

    this.set('visible', false);

    assert.dom('.alert').doesNotExist('alert has no alert class');
    assert.dom('*').hasText('', 'alert has no content');
  });

  test('onDismiss is called when clicking the close button', async function (assert) {
    let action = sinon.spy();
    this.actions.dismiss = action;
    await render(hbs`<BsAlert @type="success" @fade={{false}} @onDismiss={{action "dismiss"}}>Test</BsAlert>`);
    await click('button.close');
    assert.ok(action.calledOnce, 'onDismiss has been called.');
  });

  test('alert is not hidden after clicking the close button when onDismiss action return false', async function (assert) {
    let action = sinon.stub();
    action.returns(false);
    this.actions.dismiss = action;
    await render(hbs`<BsAlert @type="success" @fade={{false}} @onDismiss={{action "dismiss"}}>Test</BsAlert>`);
    await click('button.close');
    assert.ok(action.calledOnce, 'onDismiss has been called.');

    assert.dom('.alert').exists('alert is still visible');
  });

  test('onDismissed is called after modal is closed', async function (assert) {
    let action = sinon.spy();
    this.actions.dismissed = action;
    await render(hbs`<BsAlert @type="success" @fade={{false}} @onDismissed={{action "dismissed"}}>Test</BsAlert>`);
    await click('button.close');
    assert.ok(action.calledOnce, 'onDismissed has been called.');
  });

  test('When fade is true, onDismissed is called once when visible changes from true to false', async function (assert) {
    let action = sinon.spy();
    this.dismissed = action;
    this.isAlertShown = true;

    await render(
      hbs`<BsAlert @fade={{true}} @onDismissed={{this.dismissed}} @visible={{this.isAlertShown}}>Test</BsAlert>`
    );

    this.set('isAlertShown', false);
    await settled();

    assert.ok(action.calledOnce, 'onDismissed is called once.');
  });

  test('When fade is false, onDismissed is called once when visible changes from true to false', async function (assert) {
    let action = sinon.spy();
    this.dismissed = action;
    this.isAlertShown = true;

    await render(
      hbs`<BsAlert @fade={{false}} @onDismissed={{this.dismissed}} @visible={{this.isAlertShown}}>Test</BsAlert>`
    );

    this.set('isAlertShown', false);
    await settled();

    assert.ok(action.calledOnce, 'onDismissed is called once.');
  });

  test('When fade is false, onDismissed is not called when visible changes from false to false', async function (assert) {
    let action = sinon.spy();
    this.dismissed = action;
    this.isAlertShown = false;

    await render(
      hbs`<BsAlert @fade={{false}} @onDismissed={{this.dismissed}} @visible={{this.isAlertShown}}>Test</BsAlert>`
    );

    this.set('isAlertShown', false);
    await settled();

    assert.ok(action.notCalled, 'onDismissed is not called.');
  });

  test('alert is initially hidden when visible=false', async function (assert) {
    await render(hbs`<BsAlert @type="success" @fade={{false}} @visible={{false}}>Test</BsAlert>`);

    assert.dom('.alert').doesNotExist('alert has no alert class');
    assert.dom('*').hasText('', 'alert has no content');
  });

  test('alert can be made visible when setting visible=true', async function (assert) {
    this.set('visible', false);
    await render(hbs`<BsAlert @type="success" @visible={{visible}} @fade={{false}}>Test</BsAlert>`);
    this.set('visible', true);

    assert.dom('.alert').exists('alert has alert class');
    assert.dom('.alert').hasClass('alert-success', 'alert has type class');
  });

  test('dismissing alert does not change public visible property (DDAU)', async function (assert) {
    this.set('visible', true);
    await render(hbs`<BsAlert @type="success" @visible={{visible}} @fade={{false}}>Test</BsAlert>`);

    await click('button.close');

    assert.equal(this.visible, true, 'Does not modify visible property');
  });

  test('it passes accessibility checks', async function (assert) {
    await render(hbs`<BsAlert @type="success">Test</BsAlert>`);

    await a11yAudit();
    assert.ok(true, 'A11y audit passed');
  });
});
<|endoftext|>


<commit_before>/**
 * Appcelerator Titanium Mobile
 * Copyright (c) 2011 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 */
var tiBinding = kroll.binding('Titanium'),
	Titanium = tiBinding.Titanium,
	Proxy = tiBinding.Proxy,
	assets = kroll.binding('assets'),
	Script = kroll.binding('evals').Script,
	bootstrap = require('bootstrap'),
	path = require('path'),
	url = require('url');

var TAG = "Titanium";

//the app entry point
Titanium.sourceUrl = "app://app.js";

//a list of java APIs that need an invocation-specific URL
//passed in as the first argument
Titanium.invocationAPIs = [];

//Define lazy initializers for all Titanium APIs
bootstrap.bootstrap(Titanium);

// Custom JS extensions to Java modules
require("ui").bootstrap(Titanium);

var Properties = require("properties");
Properties.bootstrap(Titanium);

//Custom native modules
bootstrap.defineLazyBinding(Titanium, "API")

// Used just to differentiate scope vars on java side by checking
// constructor name
function ScopeVars() {};

// Context-bound modules -------------------------------------------------
//
// Specialized modules that require binding context specific data
// within a script execution scope. This is how Ti.UI.currentWindow,
// Ti.Android.currentActivity, and others are implemented.
function TitaniumWrapper(context) {
	var sourceUrl = this.sourceUrl = context.sourceUrl;

	// The "context" specific global object
	this.global = context.global;
	var self = this;

	// Special version of include to handle relative paths based on sourceUrl.
	this.include = function() {
		var baseUrl, context;
		var fileCount = arguments.length;

		var info = arguments[fileCount - 1];
		var baseUrl, context;
		if (info instanceof Array) {
			fileCount--;
			baseUrl = info[0];
			context = info[1];
		} else {
			baseUrl = sourceUrl;
			context = {};
		}

		context.global = self.global;
		for (var i = 0; i < fileCount; i++) {
			TiInclude(arguments[i], baseUrl, context);
		}
	}

	this.Android = new AndroidWrapper(context);
	this.UI = new UIWrapper(context, this.Android);

	var scopeVars = new ScopeVars();
	scopeVars.sourceUrl = sourceUrl;
	scopeVars.module = context.module;
	scopeVars.currentActivity = this.Android.currentActivity;

	Titanium.bindInvocationAPIs(this, scopeVars);
}
TitaniumWrapper.prototype = Titanium;
Titanium.Wrapper = TitaniumWrapper;

function UIWrapper(context, Android) {
	this.currentWindow = context.currentWindow;
	this.currentTab = context.currentTab;
	this.currentTabGroup = context.currentTabGroup;

	if (!context.currentWindow && Android.currentActivity) {
		this.currentWindow = Android.currentActivity.window;
	}
}
UIWrapper.prototype = Titanium.UI;

function AndroidWrapper(context) {
	this.currentActivity = context.currentActivity;
	var currentWindow = context.currentWindow;

	if (!this.currentActivity) {
		var topActivity;
		if (currentWindow && currentWindow.window && currentWindow.window.activity) {
			this.currentActivity = currentWindow.activity;

		} else if (topActivity = Titanium.App.Android.getTopActivity()) {
			this.currentActivity = topActivity;
		}
	}
}
AndroidWrapper.prototype = Titanium.Android;

// -----------------------------------------------------------------------

function createSandbox(ti) {
	var sandbox = { Ti: ti, Titanium: ti };

	if (kroll.runtime == "rhino") {
		return kroll.createSandbox(sandbox, ti.global);
	}

	return sandbox;
}

// Initializes a ScopeVars object with a
// passed in sourceURL (resolved from url.resolve)
function initScopeVars(scopeVars, sourceUrl) {
	var contextUrl = sourceUrl.href;

	if (kroll.runtime == "rhino") {
		contextUrl = require("rhino").getSourceUrl(sourceUrl);
	}

	scopeVars = scopeVars || {};
	scopeVars.sourceUrl = contextUrl;
	return scopeVars;
}
Titanium.initScopeVars = initScopeVars;

// Gets the source string for a specified URL / filename combo
function getUrlSource(filename, sourceUrl) {
	var source;

	// Load the source code for the script.
	if (!('protocol' in sourceUrl)) {
		source = assets.readAsset(filename);
	} else if (sourceUrl.filePath) {
		var filepath = url.toFilePath(sourceUrl);
		source = assets.readFile(filepath);
	} else if (sourceUrl.assetPath) {
		var assetPath = url.toAssetPath(sourceUrl);
		source = assets.readAsset(assetPath);
	} else {
		throw new Error("Unable to load source for filename: " + filename);
	}
	return source;
}
Titanium.getUrlSource = getUrlSource;

// This is the implementation of Ti.include (and it's wrappers/delegates)
// Ti.include executes code in the current "context", and
// also supports relative paths based on the current file.
//
// We have some complicated code to get this working, namely:
// - Every "context" (i.e. window with a URL, or app.js) is actually a CommonJS module in disguise, with caching disabled
// - Every "context" has it's own top level / global object
// - Ti.include code is executed in the context that it's called from
// - Each "context" and each Ti.include file gets it's own version of Ti.include / require that wraps this implementation, passing a different baseUrl
// - We use TitaniumWrapper as the base for all context / scope-specific APIs
function TiInclude(filename, baseUrl, scopeVars) {
	var sourceUrl = url.resolve(baseUrl, filename);
	scopeVars = initScopeVars(scopeVars, sourceUrl);

	// Create a context-bound Titanium module.
	var ti = new TitaniumWrapper(scopeVars);

	if (kroll.runtime == 'rhino') {
		// In Rhino we use a different code path to support pre-compiled JS
		return require("rhino").include(filename, baseUrl, createSandbox(ti));

	} else {
		var source = getUrlSource(filename, sourceUrl);

		var contextGlobal = ti.global;
		if (contextGlobal) {
			contextGlobal.sandbox = createSandbox(ti);
		} else {
			// Put sandbox on the global scope
			sandbox = createSandbox(ti);
		}

		var wrappedSource = "with(sandbox) { " + source + "\n }";

		if (contextGlobal) {
			// We're running inside another window or module, so we run against it's context
			return Script.runInContext(wrappedSource, contextGlobal, sourceUrl.href, true);
		} else {
			// We're running in the main module (app.js), so we use the global V8 Context directly.
			return Script.runInThisContext(wrappedSource, sourceUrl.href, true);
		}
	}
}
TiInclude.prototype = global;
Titanium.include = TiInclude;

Titanium.bindInvocationAPIs = function(sandboxTi, scopeVars) {
	// This loops through all known APIs that require an
	// Invocation object and wraps them so we can pass a
	// source URL as the first argument

	function genInvoker(invocationAPI) {
		var namespace = invocationAPI.namespace;
		var names = namespace.split(".");
		var length = names.length;
		if (namespace == "Titanium") {
			length = 0;
		}

		var apiNamespace = sandboxTi;
		var realAPI = tiBinding.Titanium;

		for (var j = 0, namesLen = length; j < namesLen; ++j) {
			var name = names[j];
			var api;

			// Create a module wrapper only if it hasn't been wrapped already.
			if (apiNamespace.hasOwnProperty(name)) {
				api = apiNamespace[name];
			} else {
				function SandboxAPI() {}
				SandboxAPI.prototype = apiNamespace[name];

				api = new SandboxAPI();
				apiNamespace[name] = api;
			}

			apiNamespace = api;
			realAPI = realAPI[name];
		}

		var delegate = realAPI[invocationAPI.api];

		// These invokers form a call hierarchy so we need to
		// provide a way back to the actual root Titanium / actual impl.
		while (delegate.__delegate__) {
			delegate = delegate.__delegate__;
		}

		function createInvoker(delegate) {
			var urlInvoker = function invoker() {
				var args = Array.prototype.slice.call(arguments);
				args.splice(0, 0, invoker.scopeVars);

				return delegate.apply(invoker.__thisObj__, args);
			}

			urlInvoker.scopeVars = scopeVars;
			urlInvoker.__delegate__ = delegate;
			urlInvoker.__thisObj__ = realAPI;

			return urlInvoker;
		}

		apiNamespace[invocationAPI.api] = createInvoker(delegate);
	}

	var len = Titanium.invocationAPIs.length;
	for (var i = 0; i < len; ++i) {
		// separate each invoker into it's own private scope
		genInvoker(Titanium.invocationAPIs[i]);
	}
}

Titanium.Proxy = Proxy;

// Use defineProperty so we can avoid our custom extensions being enumerated
Object.defineProperty(Object.prototype, "extend", {
	value: function(other) {
		if (!other) return;

		for (var name in other) {
			if (other.hasOwnProperty(name)) {
				this[name] = other[name];
			}
		}
		return this;
	},
	enumerable: false
});

Proxy.defineProperties = function(proxyPrototype, names) {
	var properties = {};
	var len = names.length;

	for (var i = 0; i < len; ++i) {
		var name = names[i];
		properties[name] = {
			get: function() { return this.getProperty(name); },
			set: function(value) { this.setPropertyAndFire(name, value); },
			enumerable: true
		};
	}

	Object.defineProperties(proxyPrototype, properties);
}

Object.defineProperty(Proxy.prototype, "getProperty", {
	value: function(property) {
		return this._properties[property];
	},
	enumerable: false
});

Object.defineProperty(Proxy.prototype, "setProperty", {
	value: function(property, value) {
		return this._properties[property] = value;
	},
	enumerable: false
});

Object.defineProperty(Proxy.prototype, "setPropertiesAndFire", {
	value: function(properties) {
		var ownNames = Object.getOwnPropertyNames(properties);
		var len = ownNames.length;
		var changes = [];

		for (var i = 0; i < len; ++i) {
			var property = ownNames[i];
			var value = properties[property];

			if (!property) continue;

			var oldValue = this._properties[property];
			this._properties[property] = value;

			if (value != oldValue) {
				changes.push([property, oldValue, value]);
			}
		}

		if (changes.length > 0) {
			this.onPropertiesChanged(changes);
		}
	},
	enumerable: false
});

// Custom native modules
bootstrap.defineLazyBinding(Titanium, "API");

Object.defineProperty(Titanium, "Yahoo", {
	get: function() {
		delete this.Yahoo;
		delete this.__proto__.Yahoo;

		var value = require("yahoo").bootstrap(Titanium);
		this.Yahoo = this.__proto__.Yahoo = value;

		return value;
	}
});

// Do not serialize the parent view. Doing so will result
// in a circular reference loop.
Object.defineProperty(Titanium.TiView.prototype, "toJSON", {
	value: function () {
		var keys = Object.keys(this);
		var keyCount = keys.length;
		var serialized = {};

		for (var i = 0; i < keyCount; i++) {
			var k = keys[i];
			if (k === "parent") {
				continue;
			}
			serialized[k] = this[k];
		}

		return serialized;
	},
	enumerable: false
});

Object.defineProperty(Titanium.Activity.prototype, "toJSON", {
	value: function () {
		var keys = Object.keys(this);
		var keyCount = keys.length;
		var serialized = {};

		for (var i = 0; i < keyCount; i++) {
			var k = keys[i];
			if (k === "activity" || k === "window" || k === "intent") {
				continue;
			}
			serialized[k] = this[k];
		}

		return serialized;
	},
	enumerable: false
});

module.exports = new TitaniumWrapper({
	sourceUrl: Titanium.sourceUrl
});
<commit_msg>regroup logic in titanium.js to avoid a separate check TIMOB-6073<commit_after>/**
 * Appcelerator Titanium Mobile
 * Copyright (c) 2011 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 */
var tiBinding = kroll.binding('Titanium'),
	Titanium = tiBinding.Titanium,
	Proxy = tiBinding.Proxy,
	assets = kroll.binding('assets'),
	Script = kroll.binding('evals').Script,
	bootstrap = require('bootstrap'),
	path = require('path'),
	url = require('url');

var TAG = "Titanium";

//the app entry point
Titanium.sourceUrl = "app://app.js";

//a list of java APIs that need an invocation-specific URL
//passed in as the first argument
Titanium.invocationAPIs = [];

//Define lazy initializers for all Titanium APIs
bootstrap.bootstrap(Titanium);

// Custom JS extensions to Java modules
require("ui").bootstrap(Titanium);

var Properties = require("properties");
Properties.bootstrap(Titanium);

//Custom native modules
bootstrap.defineLazyBinding(Titanium, "API")

// Used just to differentiate scope vars on java side by checking
// constructor name
function ScopeVars() {};

// Context-bound modules -------------------------------------------------
//
// Specialized modules that require binding context specific data
// within a script execution scope. This is how Ti.UI.currentWindow,
// Ti.Android.currentActivity, and others are implemented.
function TitaniumWrapper(context) {
	var sourceUrl = this.sourceUrl = context.sourceUrl;

	// The "context" specific global object
	this.global = context.global;
	var self = this;

	// Special version of include to handle relative paths based on sourceUrl.
	this.include = function() {
		var baseUrl, context;
		var fileCount = arguments.length;

		var info = arguments[fileCount - 1];
		var baseUrl, context;
		if (info instanceof Array) {
			fileCount--;
			baseUrl = info[0];
			context = info[1];
		} else {
			baseUrl = sourceUrl;
			context = {};
		}

		context.global = self.global;
		for (var i = 0; i < fileCount; i++) {
			TiInclude(arguments[i], baseUrl, context);
		}
	}

	this.Android = new AndroidWrapper(context);
	this.UI = new UIWrapper(context, this.Android);

	var scopeVars = new ScopeVars();
	scopeVars.sourceUrl = sourceUrl;
	scopeVars.module = context.module;
	scopeVars.currentActivity = this.Android.currentActivity;

	Titanium.bindInvocationAPIs(this, scopeVars);
}
TitaniumWrapper.prototype = Titanium;
Titanium.Wrapper = TitaniumWrapper;

function UIWrapper(context, Android) {
	this.currentWindow = context.currentWindow;
	this.currentTab = context.currentTab;
	this.currentTabGroup = context.currentTabGroup;

	if (!context.currentWindow && Android.currentActivity) {
		this.currentWindow = Android.currentActivity.window;
	}
}
UIWrapper.prototype = Titanium.UI;

function AndroidWrapper(context) {
	this.currentActivity = context.currentActivity;
	var currentWindow = context.currentWindow;

	if (!this.currentActivity) {
		var topActivity;
		if (currentWindow && currentWindow.window && currentWindow.window.activity) {
			this.currentActivity = currentWindow.activity;

		} else if (topActivity = Titanium.App.Android.getTopActivity()) {
			this.currentActivity = topActivity;
		}
	}
}
AndroidWrapper.prototype = Titanium.Android;

// -----------------------------------------------------------------------

function createSandbox(ti) {
	var sandbox = { Ti: ti, Titanium: ti };

	if (kroll.runtime == "rhino") {
		return kroll.createSandbox(sandbox, ti.global);
	}

	return sandbox;
}

// Initializes a ScopeVars object with a
// passed in sourceURL (resolved from url.resolve)
function initScopeVars(scopeVars, sourceUrl) {
	var contextUrl = sourceUrl.href;

	if (kroll.runtime == "rhino") {
		contextUrl = require("rhino").getSourceUrl(sourceUrl);
	}

	scopeVars = scopeVars || {};
	scopeVars.sourceUrl = contextUrl;
	return scopeVars;
}
Titanium.initScopeVars = initScopeVars;

// Gets the source string for a specified URL / filename combo
function getUrlSource(filename, sourceUrl) {
	var source;

	// Load the source code for the script.
	if (!('protocol' in sourceUrl)) {
		source = assets.readAsset(filename);
	} else if (sourceUrl.filePath) {
		var filepath = url.toFilePath(sourceUrl);
		source = assets.readFile(filepath);
	} else if (sourceUrl.assetPath) {
		var assetPath = url.toAssetPath(sourceUrl);
		source = assets.readAsset(assetPath);
	} else {
		throw new Error("Unable to load source for filename: " + filename);
	}
	return source;
}
Titanium.getUrlSource = getUrlSource;

// This is the implementation of Ti.include (and it's wrappers/delegates)
// Ti.include executes code in the current "context", and
// also supports relative paths based on the current file.
//
// We have some complicated code to get this working, namely:
// - Every "context" (i.e. window with a URL, or app.js) is actually a CommonJS module in disguise, with caching disabled
// - Every "context" has it's own top level / global object
// - Ti.include code is executed in the context that it's called from
// - Each "context" and each Ti.include file gets it's own version of Ti.include / require that wraps this implementation, passing a different baseUrl
// - We use TitaniumWrapper as the base for all context / scope-specific APIs
function TiInclude(filename, baseUrl, scopeVars) {
	var sourceUrl = url.resolve(baseUrl, filename);
	scopeVars = initScopeVars(scopeVars, sourceUrl);

	// Create a context-bound Titanium module.
	var ti = new TitaniumWrapper(scopeVars);

	if (kroll.runtime == 'rhino') {
		// In Rhino we use a different code path to support pre-compiled JS
		return require("rhino").include(filename, baseUrl, createSandbox(ti));

	} else {
		var source = getUrlSource(filename, sourceUrl);
		var wrappedSource = "with(sandbox) { " + source + "\n }";
		var contextGlobal = ti.global;

		if (contextGlobal) {
			// We're running inside another window or module, so we run against it's context
			contextGlobal.sandbox = createSandbox(ti);
			return Script.runInContext(wrappedSource, contextGlobal, sourceUrl.href, true);

		} else {
			// We're running in the main module (app.js), so we use the global V8 Context directly.
			// Put sandbox on the global scope
			sandbox = createSandbox(ti);
			return Script.runInThisContext(wrappedSource, sourceUrl.href, true);
		}
	}
}
TiInclude.prototype = global;
Titanium.include = TiInclude;

Titanium.bindInvocationAPIs = function(sandboxTi, scopeVars) {
	// This loops through all known APIs that require an
	// Invocation object and wraps them so we can pass a
	// source URL as the first argument

	function genInvoker(invocationAPI) {
		var namespace = invocationAPI.namespace;
		var names = namespace.split(".");
		var length = names.length;
		if (namespace == "Titanium") {
			length = 0;
		}

		var apiNamespace = sandboxTi;
		var realAPI = tiBinding.Titanium;

		for (var j = 0, namesLen = length; j < namesLen; ++j) {
			var name = names[j];
			var api;

			// Create a module wrapper only if it hasn't been wrapped already.
			if (apiNamespace.hasOwnProperty(name)) {
				api = apiNamespace[name];
			} else {
				function SandboxAPI() {}
				SandboxAPI.prototype = apiNamespace[name];

				api = new SandboxAPI();
				apiNamespace[name] = api;
			}

			apiNamespace = api;
			realAPI = realAPI[name];
		}

		var delegate = realAPI[invocationAPI.api];

		// These invokers form a call hierarchy so we need to
		// provide a way back to the actual root Titanium / actual impl.
		while (delegate.__delegate__) {
			delegate = delegate.__delegate__;
		}

		function createInvoker(delegate) {
			var urlInvoker = function invoker() {
				var args = Array.prototype.slice.call(arguments);
				args.splice(0, 0, invoker.scopeVars);

				return delegate.apply(invoker.__thisObj__, args);
			}

			urlInvoker.scopeVars = scopeVars;
			urlInvoker.__delegate__ = delegate;
			urlInvoker.__thisObj__ = realAPI;

			return urlInvoker;
		}

		apiNamespace[invocationAPI.api] = createInvoker(delegate);
	}

	var len = Titanium.invocationAPIs.length;
	for (var i = 0; i < len; ++i) {
		// separate each invoker into it's own private scope
		genInvoker(Titanium.invocationAPIs[i]);
	}
}

Titanium.Proxy = Proxy;

// Use defineProperty so we can avoid our custom extensions being enumerated
Object.defineProperty(Object.prototype, "extend", {
	value: function(other) {
		if (!other) return;

		for (var name in other) {
			if (other.hasOwnProperty(name)) {
				this[name] = other[name];
			}
		}
		return this;
	},
	enumerable: false
});

Proxy.defineProperties = function(proxyPrototype, names) {
	var properties = {};
	var len = names.length;

	for (var i = 0; i < len; ++i) {
		var name = names[i];
		properties[name] = {
			get: function() { return this.getProperty(name); },
			set: function(value) { this.setPropertyAndFire(name, value); },
			enumerable: true
		};
	}

	Object.defineProperties(proxyPrototype, properties);
}

Object.defineProperty(Proxy.prototype, "getProperty", {
	value: function(property) {
		return this._properties[property];
	},
	enumerable: false
});

Object.defineProperty(Proxy.prototype, "setProperty", {
	value: function(property, value) {
		return this._properties[property] = value;
	},
	enumerable: false
});

Object.defineProperty(Proxy.prototype, "setPropertiesAndFire", {
	value: function(properties) {
		var ownNames = Object.getOwnPropertyNames(properties);
		var len = ownNames.length;
		var changes = [];

		for (var i = 0; i < len; ++i) {
			var property = ownNames[i];
			var value = properties[property];

			if (!property) continue;

			var oldValue = this._properties[property];
			this._properties[property] = value;

			if (value != oldValue) {
				changes.push([property, oldValue, value]);
			}
		}

		if (changes.length > 0) {
			this.onPropertiesChanged(changes);
		}
	},
	enumerable: false
});

// Custom native modules
bootstrap.defineLazyBinding(Titanium, "API");

Object.defineProperty(Titanium, "Yahoo", {
	get: function() {
		delete this.Yahoo;
		delete this.__proto__.Yahoo;

		var value = require("yahoo").bootstrap(Titanium);
		this.Yahoo = this.__proto__.Yahoo = value;

		return value;
	}
});

// Do not serialize the parent view. Doing so will result
// in a circular reference loop.
Object.defineProperty(Titanium.TiView.prototype, "toJSON", {
	value: function () {
		var keys = Object.keys(this);
		var keyCount = keys.length;
		var serialized = {};

		for (var i = 0; i < keyCount; i++) {
			var k = keys[i];
			if (k === "parent") {
				continue;
			}
			serialized[k] = this[k];
		}

		return serialized;
	},
	enumerable: false
});

Object.defineProperty(Titanium.Activity.prototype, "toJSON", {
	value: function () {
		var keys = Object.keys(this);
		var keyCount = keys.length;
		var serialized = {};

		for (var i = 0; i < keyCount; i++) {
			var k = keys[i];
			if (k === "activity" || k === "window" || k === "intent") {
				continue;
			}
			serialized[k] = this[k];
		}

		return serialized;
	},
	enumerable: false
});

module.exports = new TitaniumWrapper({
	sourceUrl: Titanium.sourceUrl
});
<|endoftext|>


<commit_before>const COLORS = ["black","brown","red","orange","yellow","green","blue","violet","grey","white"]
const colorCode = color =>  COLORS.indexOf(color).toString();

export const value = ([color_1, color_2]) => {
  return Number(colorCode(color_1.toLowerCase()) + colorCode(color_2.toLowerCase()));
};
<commit_msg>Une solution à l'exercice resistor-color-duo d'exercism en exploitant map et join<commit_after>const COLORS = ["black","brown","red","orange","yellow","green","blue","violet","grey","white"]

export const value = (colors) => {
  return Number(colors.map(color =>  COLORS.indexOf(color.toLowerCase()).toString()).join(''));
};
<|endoftext|>