<commit_before>/**
 * @class  	UIUtil
 * @author  <NAME> <<EMAIL>>
 */

var Image = require('T/image');
var HTTP = require('T/http');

/**
 * @method populateListViewFromCollection
 * Parse an array or a Backbone.Collection and populate a ListView with this values.
 *
 * @param {Object} C Array or Backbone.Collection
 * @param {Object} opt Options
 * @param {Function} opt.datasetCb You must provide a callback to fill the ListItem, like this:
 *
 * ```
 * return {
 *	   properties: {
 *	      height: 52,
 *			itemId: el.id,
 *			searchableText: el.get('city')
 *		},
 *		title: { text: el.get('title') },
 *		address: { text: el.get('address')+', '+el.get('city') }
 *	}
 * ```
 *
 * @param {Object} opt.groupBy See `_.groupBy`
 * @param {Function} opt.headerViewCb A callback to generate the headerView for the ListView.
 * @param {Boolean} opt.sectionIndex If `true`, provide the **alphabet on the right** functionality.
 * @param {Ti.UI.ListView} [$ui] The ListView to populate.
 * @return {Array}
 */
exports.populateListViewFromCollection = function(C, opt, $ui) {
	var sec = [];

	if (opt.groupBy != null && opt.groupBy != false) {

		var array = (C instanceof Backbone.Collection) ? C.groupBy(opt.groupBy) : ( _.isArray(C) ? _.groupBy(C, opt.groupBy) : C );
		sec = _.map(array, function(els, key) {
			var hViewExtend = _.isFunction(opt.headerViewCb) ? { headerView: opt.headerViewCb(key) } : { headerTitle: key };

			return Ti.UI.createListSection(_.extend({
				items: _.map(els, opt.datasetCb),
			}, hViewExtend));
		});

		if (OS_IOS && $ui != null && opt.sectionIndex == true) {
			$ui.sectionIndexTitles = _.map(Object.keys(array), function(u, k) {
				return {
					title: u,
					index: k
				};
			});
		}

	} else {
		sec = [ Ti.UI.createListSection({
			items: (C instanceof Backbone.Collection) ? C.map(opt.datasetCb) : _.map(C, opt.datasetCb)
		}) ];
	}

	if ($ui != null) $ui.sections = sec;
	return sec;
};



/**
* @method setBackgroundCoverForView
* Set the background image with cover method
* @param {String} url
*/
exports.setBackgroundCoverForView = function($this, url, callback) {
	if ($this.size == null || $this.size.width == 0 || $this.size.height == 0) {

		$this.addEventListener('postlayout', function postlayout() {
			$this.removeEventListener('postlayout', postlayout);
			if ($this.size != null && $this.size.width != 0 && $this.size.height != 0) {
				exports.setBackgroundCoverForView($this, url, callback);
			}
		});

		return;
	}

	var w = $this.size.width, h = $this.size.height;
	var hashedCachedName = Ti.Utils.md5HexDigest(url) + '_' + (w+'x'+h) + '.png';
	var cachedFile = Ti.Filesystem.getFile(Ti.Filesystem.applicationCacheDirectory, hashedCachedName);

	var onBlobReady = function(blob) {
		Ti.Filesystem.getFile(Ti.Filesystem.applicationCacheDirectory).createDirectory();

		var cachedFileStatus = Image.process({
			blob: blob,
			width: w,
			height: h,
			retina: true,
			file: cachedFile
		});

		if (cachedFileStatus != false && cachedFileStatus.nativePath) {
			callback(cachedFileStatus.nativePath);
		} else {
			Ti.API.error('UIUtil: Can\'t write cover file for url <' + url + '>');<commit_msg>Fixed UIUtil.setBackgroundCoverForView to check for write permissions<commit_after>/**
 * @class  	UIUtil
 * @author  <NAME> <<EMAIL>>
 */

var Image = require('T/image');
var HTTP = require('T/http');

/**
 * @method populateListViewFromCollection
 * Parse an array or a Backbone.Collection and populate a ListView with this values.
 *
 * @param {Object} C Array or Backbone.Collection
 * @param {Object} opt Options
 * @param {Function} opt.datasetCb You must provide a callback to fill the ListItem, like this:
 *
 * ```
 * return {
 *	   properties: {
 *	      height: 52,
 *			itemId: el.id,
 *			searchableText: el.get('city')
 *		},
 *		title: { text: el.get('title') },
 *		address: { text: el.get('address')+', '+el.get('city') }
 *	}
 * ```
 *
 * @param {Object} opt.groupBy See `_.groupBy`
 * @param {Function} opt.headerViewCb A callback to generate the headerView for the ListView.
 * @param {Boolean} opt.sectionIndex If `true`, provide the **alphabet on the right** functionality.
 * @param {Ti.UI.ListView} [$ui] The ListView to populate.
 * @return {Array}
 */
exports.populateListViewFromCollection = function(C, opt, $ui) {
	var sec = [];

	if (opt.groupBy != null && opt.groupBy != false) {

		var array = (C instanceof Backbone.Collection) ? C.groupBy(opt.groupBy) : ( _.isArray(C) ? _.groupBy(C, opt.groupBy) : C );
		sec = _.map(array, function(els, key) {
			var hViewExtend = _.isFunction(opt.headerViewCb) ? { headerView: opt.headerViewCb(key) } : { headerTitle: key };

			return Ti.UI.createListSection(_.extend({
				items: _.map(els, opt.datasetCb),
			}, hViewExtend));
		});

		if (OS_IOS && $ui != null && opt.sectionIndex == true) {
			$ui.sectionIndexTitles = _.map(Object.keys(array), function(u, k) {
				return {
					title: u,
					index: k
				};
			});
		}

	} else {
		sec = [ Ti.UI.createListSection({
			items: (C instanceof Backbone.Collection) ? C.map(opt.datasetCb) : _.map(C, opt.datasetCb)
		}) ];
	}

	if ($ui != null) $ui.sections = sec;
	return sec;
};



/**
* @method setBackgroundCoverForView
* Set the background image with cover method
* @param {String} url
*/
exports.setBackgroundCoverForView = function($this, url, callback) {
	if ($this.size == null || $this.size.width == 0 || $this.size.height == 0) {

		$this.addEventListener('postlayout', function postlayout() {
			$this.removeEventListener('postlayout', postlayout);
			if ($this.size != null && $this.size.width != 0 && $this.size.height != 0) {
				exports.setBackgroundCoverForView($this, url, callback);
			}
		});

		return;
	}

	var w = $this.size.width, h = $this.size.height;
	var hashedCachedName = Ti.Utils.md5HexDigest(url) + '_' + (w+'x'+h) + '.png';
	var cachedFile = Ti.Filesystem.getFile(Ti.Filesystem.applicationCacheDirectory, hashedCachedName);

	var onBlobReady = function(blob) {
		if (Ti.Filesystem.hasStoragePermissions() === true) {
			// Cache the file to avoid future calls
			Ti.Filesystem.getFile(Ti.Filesystem.applicationCacheDirectory).createDirectory();

			var cachedFileStatus = Image.process({
				blob: blob,
				width: w,
				height: h,
				retina: true,
				file: cachedFile
			});

			if (cachedFileStatus != false && cachedFileStatus.nativePath) {
				callback(cachedFileStatus.nativePath);
			} else {
				Ti.API.error('UIUtil: Can\'t write cover file for url <' + url + '>');
			}
		} else {
			// fall back to the original file
			// TODO this is needed because of a bug in how Titanium handles storage permissions:
			// applicationCacheDirectory and other directories shouldn't need storage permissions, but they do.
			// This will be fixed in Titanium 5.4.0. Maybe.
			// See: https://jira.appcelerator.org/browse/TIMOB-20440
			Ti.API.error('UIUtil: Missing storage permissions, using original file <' + url + '>');

			callback(url);
{'fraction_non_alphanumeric': 0.15924755887421022, 'fraction_numerical': 0.0031591039632395176, 'mean_word_length': 3.6997300944669367, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 12, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5858086', 'n_tokens_mistral': 2564, 'n_tokens_neox': 2315, 'n_words': 583}