<commit_before>var _ = require('lodash');
var pretty = require('./prettyprint').pretty;
var Vampire = Parse.Object.extend("Vampire");
var Patronage = Parse.Object.extend("Patronage");
var Image = require("jimp");
var request = require("request");
var Promise = global.Promise;
var moment = require("moment");

// Use Parse.Cloud.define to define as many cloud functions as you want.
// For example:
Parse.Cloud.define("hello", function(request, response) {
  response.success("Hello world!");
});

var create_thumbnail = function(portrait, input_image, size) {
    var promise = new Promise(
        function(resolve, reject) {
            cb = function(err, buffer) {
                    if (err) reject(err);
                    else resolve(buffer);
                }
            var img = input_image.getBuffer(Image.MIME_JPEG, cb);
        }
    );
    return promise.then(function (buffer) {
        return Image.read(buffer);
    }).then(function(image) {
        return new Promise(
            function(resolve, reject) {
                cb = function(err, unused) {
                    if (err) reject(err);
                    else resolve(image);
                }
                var img = image.scaleToFit(size, size, cb);
            }
        );
    }).then(function (image) {
        return new Promise(
            function (resolve, reject) {
                cb = function (err, buffer) {
                    if (err) reject(err);
                    else resolve(buffer);
                }
                var img = image.getBuffer(Image.MIME_JPEG, cb);
            }
        );
    }).then(function (buffer) {
        var base64 = buffer.toString("base64");
        var cropped = new Parse.File("thumbnail_" + size + ".jpg", {base64: base64});
        return cropped.save();
    }).then(function(cropped) {
        portrait.set("thumb_" + size, cropped);
    });
}

var crop_and_thumb = function(req, res) {
    var portrait = req.object;
    var THUMBNAIL_SIZES = [32, 64, 128, 256];
    var needed_sizes = [];

    if (portrait.dirty("original")) {
        _.each(THUMBNAIL_SIZES, function (size) {
            portrait.set("thumb_" + size, undefined);
        });
    }

    _.each(THUMBNAIL_SIZES, function (size) {
        if (!portrait.get("thumb_" + size)) {
            needed_sizes.push(size);
        }
    })

    if (0 == needed_sizes.length) {
        res.success();
        return;
    }

    Image.read(portrait.get("original").url()).then(function (image) {
        // Crop the image to the smaller of width or height.
        var size = Math.min(image.bitmap.width, image.bitmap.height);
        return image.crop(
            (image.bitmap.width - size) / 2,
            (image.bitmap.height - size) / 2,
            size,
            size
        );
    }).then(function (image) {
        var promises = [];
        _.each(THUMBNAIL_SIZES, function (size) {
            promises.push(create_thumbnail(portrait, image, size))
        })
        return Parse.Promise.when(promises);
    }).then(function () {
        res.success();
    }, function (error) {
        res.error(error);
    });
};

Parse.Cloud.beforeSave("TroupePortrait", function(request, response) {
    crop_and_thumb(request, response);
});

Parse.Cloud.beforeSave("CharacterPortrait", function(request, response) {
    crop_and_thumb(request, response);
});

var get_vampire_change_acl = function(vampire) {
    var daString = vampire.get("acl_to_json");
    if (_.isUndefined(daString)) {
        var acl = new Parse.ACL;
        acl.setPublicReadAccess(false);
        acl.setPublicWriteAccess(false);
        var owner = vampire.get("owner");
        if (!_.isUndefined(owner)) {
            // Archived characters have no owner
            acl.setReadAccess(owner, true);
            acl.setWriteAccess(owner, false);
        }
        acl.setRoleReadAccess("Administrator", true);
        acl.setRoleWriteAccess("Administrator", true);
        return acl;
    }
    var acl = new Parse.ACL;
    var given_permissions_by_id = JSON.parse(daString);
    _.each(given_permissions_by_id, function (permissions, key) {
        acl.setReadAccess(key, true);
        acl.setWriteAccess(key, false);
    });
    acl.setPublicReadAccess(false);
    acl.setPublicWriteAccess(false);
    acl.setRoleReadAccess("Administrator", true);
    acl.setRoleWriteAccess("Administrator", false);
    return acl;
}

Parse.Cloud.beforeSave("Vampire", function(request, response) {
    var tracked_texts = ["name", "clan", "state", "archetype", "faction", "title", "sect", "antecedence"];
    var v = request.object;
    var desired_changes = _.intersection(tracked_texts, v.dirtyKeys());
    if (0 === desired_changes.length) {
        console.log("Saving vampire (" + v.id + ") and there are no changes we track here");
        return response.success();
    }
    // TODO: Update the history permissions if troupes has changed
    var new_values = {};
    _.each(v.dirtyKeys(), function(k) {
        new_values[k] = v.get(k);
    })
    var vToFetch = new Vampire({id: v.id});
    vToFetch.fetch({useMasterKey: true}).then(function(vampire) {
        return Parse.Object.saveAll(_.map(_.toPairs(new_values), function(a) {
            var attribute = a[0], val = a[1];<commit_msg>Fix broke character creation with name tracking<commit_after>var _ = require('lodash');
var pretty = require('./prettyprint').pretty;
var Vampire = Parse.Object.extend("Vampire");
var Patronage = Parse.Object.extend("Patronage");
var Image = require("jimp");
var request = require("request");
var Promise = global.Promise;
var moment = require("moment");

// Use Parse.Cloud.define to define as many cloud functions as you want.
// For example:
Parse.Cloud.define("hello", function(request, response) {
  response.success("Hello world!");
});

var create_thumbnail = function(portrait, input_image, size) {
    var promise = new Promise(
        function(resolve, reject) {
            cb = function(err, buffer) {
                    if (err) reject(err);
                    else resolve(buffer);
                }
            var img = input_image.getBuffer(Image.MIME_JPEG, cb);
        }
    );
    return promise.then(function (buffer) {
        return Image.read(buffer);
    }).then(function(image) {
        return new Promise(
            function(resolve, reject) {
                cb = function(err, unused) {
                    if (err) reject(err);
                    else resolve(image);
                }
                var img = image.scaleToFit(size, size, cb);
            }
        );
    }).then(function (image) {
        return new Promise(
            function (resolve, reject) {
                cb = function (err, buffer) {
                    if (err) reject(err);
                    else resolve(buffer);
                }
                var img = image.getBuffer(Image.MIME_JPEG, cb);
            }
        );
    }).then(function (buffer) {
        var base64 = buffer.toString("base64");
        var cropped = new Parse.File("thumbnail_" + size + ".jpg", {base64: base64});
        return cropped.save();
    }).then(function(cropped) {
        portrait.set("thumb_" + size, cropped);
    });
}

var crop_and_thumb = function(req, res) {
    var portrait = req.object;
    var THUMBNAIL_SIZES = [32, 64, 128, 256];
    var needed_sizes = [];

    if (portrait.dirty("original")) {
        _.each(THUMBNAIL_SIZES, function (size) {
            portrait.set("thumb_" + size, undefined);
        });
    }

    _.each(THUMBNAIL_SIZES, function (size) {
        if (!portrait.get("thumb_" + size)) {
            needed_sizes.push(size);
        }
    })

    if (0 == needed_sizes.length) {
        res.success();
        return;
    }

    Image.read(portrait.get("original").url()).then(function (image) {
        // Crop the image to the smaller of width or height.
        var size = Math.min(image.bitmap.width, image.bitmap.height);
        return image.crop(
            (image.bitmap.width - size) / 2,
            (image.bitmap.height - size) / 2,
            size,
            size
        );
    }).then(function (image) {
        var promises = [];
        _.each(THUMBNAIL_SIZES, function (size) {
            promises.push(create_thumbnail(portrait, image, size))
        })
        return Parse.Promise.when(promises);
    }).then(function () {
        res.success();
    }, function (error) {
        res.error(error);
    });
};

Parse.Cloud.beforeSave("TroupePortrait", function(request, response) {
    crop_and_thumb(request, response);
});

Parse.Cloud.beforeSave("CharacterPortrait", function(request, response) {
    crop_and_thumb(request, response);
});

var get_vampire_change_acl = function(vampire) {
    var daString = vampire.get("acl_to_json");
    if (_.isUndefined(daString)) {
        var acl = new Parse.ACL;
        acl.setPublicReadAccess(false);
        acl.setPublicWriteAccess(false);
        var owner = vampire.get("owner");
        if (!_.isUndefined(owner)) {
            // Archived characters have no owner
            acl.setReadAccess(owner, true);
            acl.setWriteAccess(owner, false);
        }
        acl.setRoleReadAccess("Administrator", true);
        acl.setRoleWriteAccess("Administrator", true);
        return acl;
    }
    var acl = new Parse.ACL;
    var given_permissions_by_id = JSON.parse(daString);
    _.each(given_permissions_by_id, function (permissions, key) {
        acl.setReadAccess(key, true);
        acl.setWriteAccess(key, false);
    });
    acl.setPublicReadAccess(false);
    acl.setPublicWriteAccess(false);
    acl.setRoleReadAccess("Administrator", true);
    acl.setRoleWriteAccess("Administrator", false);
    return acl;
}

Parse.Cloud.beforeSave("Vampire", function(request, response) {
    var tracked_texts = ["name", "clan", "state", "archetype", "faction", "title", "sect", "antecedence"];
    var v = request.object;
    var desired_changes = _.intersection(tracked_texts, v.dirtyKeys());
    if (0 === desired_changes.length) {
        console.log("Saving vampire (" + v.id + ") and there are no changes we track here");
        return response.success();
    }
    
    var modified_vampire = request.object;
    if (_.isUndefined(modified_vampire.id)) {
        console.log("Creating a new vampire named " + request.object.get("name"));
        return response.success();
    }
    
    // TODO: Update the history permissions if troupes has changed
    
    var new_values = {};
    _.each(v.dirtyKeys(), function(k) {
        new_values[k] = v.get(k);
    })
    var vToFetch = new Vampire({id: v.id});
    vToFetch.fetch({useMasterKey: true}).then(function(vampire) {
        return Parse.Object.saveAll(_.map(_.toPairs(new_values), function(a) {
            var attribute = a[0], val = a[1];
{'fraction_non_alphanumeric': 0.13812256989446398, 'fraction_numerical': 0.004443621551564525, 'mean_word_length': 2.3854591037292385, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, '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': '4173502', 'n_tokens_mistral': 3327, 'n_tokens_neox': 3218, 'n_words': 696}