<commit_before>var debug = require('debug')('openframe:apiserver:model:Frame'),
    loopback = require('loopback');

module.exports = function(Frame) {
    Frame.disableRemoteMethod('createChangeStream', true);

    // whenever a Frame model is saved, broadcast an update event
    Frame.observe('after save', function(ctx, next) {
        if (ctx.instance && Frame.app.pubsub) {
            debug('Saved %s#%s', ctx.Model.modelName, ctx.instance.id);
            if (ctx.isNewInstance) {
                debug('New Frame, publishing: /user/' + ctx.instance.ownerId + '/frame/new');
                Frame.app.pubsub.publish('/user/' + ctx.instance.ownerId + '/frame/new', ctx.instance.id);
            } else {
                debug('Existing Frame, publishing: /frame/' + ctx.instance.id + '/db_updated');
                debug(ctx.instance);
                Frame.findById(ctx.instance.id, { include: 'current_artwork' }, function(err, frame) {
                    debug(err, frame);
                    Frame.app.pubsub.publish('/frame/' + frame.id + '/db_updated', frame);
                });
            }
        }
        next();
    });

    // Ouch. Ow. Yowsers. Serisously?
    function removeManagers(frame, managers) {
        return new Promise((resolve, reject) => {
            frame.managers(function(err, current_managers) {
                if (current_managers.length) {
                    var count = 0,
                        total = current_managers.length;
                    current_managers.forEach(function(cur_man) {
                        if (managers.indexOf(cur_man.username) === -1) {
                            frame.managers.remove(cur_man, function(err) {
                                if (err) debug(err);
                                count++;
                                if (count === total) {
                                    // all who are no longer present in the new list have been removed
                                    resolve();
                                }
                            });
                        } else {
                            count++;
                            if (count === total) {
                                // all who are no longer present in the new list have been removed
                                resolve();
                            }
                        }
                    });
                } else {
                    // there are no current managers
                    resolve();
                }
            });
        });
    }

    // Painful painful painful -- so gross. Why loopback, why!?
    function addManagers(frame, managers) {
        var OpenframeUser = Frame.app.models.OpenframeUser;

        return new Promise((resolve, reject) => {
            OpenframeUser.find({ where: { username: { inq: managers }}}, function(err, users) {
                if (err) {
                    debug(err);
                }
                var count = 0,
                    total = users.length;
                if (total === 0) {
                    // no managers found by username, return frame including current managers
                    Frame.findById(frame.id, {include: 'managers'}, function(err, frame) {
                        debug(err, frame);
                        resolve(frame);
                    });
                } else {
                    // managers found by username, add them to frame, then
                    // return frame including current managers
                    // XXX: Unfortunately loopback doesn't seem to provide a way to batch
                    // update hasAndBelongsToMany relationships :/
                    users.forEach(function(user) {
                        frame.managers.add(user, function(err) {
                            count++;
                            if (count === total) {
                                Frame.findById(frame.id, {include: 'managers'}, function(err, frame) {
                                    debug(err, frame);
                                    resolve(frame);
                                });
                            }
                        });
                    });
                }

            });
        });
    }

    // Update managers by username
    //
    // XXX: This is incredibly ugly. Loopback doesn't provide a good way to update
    // this type of relationship all in one go, which makes it a huge messy pain. Given
    // time, I may fix this.
    Frame.prototype.update_managers_by_username = function(managers, cb) {
        debug(managers);
        var self = this;

        removeManagers(self, managers)
            .then(function() {
                addManagers(self, managers)
                    .then(function(frame) {
                        cb(null, frame);
                    })
                    .catch(debug);
            }).catch(debug);
    };

    // Expose update_managers_by_username remote method
    Frame.remoteMethod(
        'update_managers_by_username', {
            description: 'Add a related item by username for managers.',
            accepts: {
                arg: 'managers',
                type: 'array',
                http: {
                    source: 'body'
                }
            },
            http: {
                verb: 'put',
                path: '/managers/by_username'
            },
            isStatic: false,
            returns: {
                arg: 'frame',
                type: 'Object'
            }
        }
    );



    /**
     * Update the current artwork by artwork ID
     * @param  {String}   currentArtworkId
     * @param  {Function} callback
     */
    Frame.prototype.update_current_artwork = function(currentArtworkId, cb) {
        debug(currentArtworkId);
        var self = this;
        self.updateAttribute('currentArtworkId', currentArtworkId, function(err, instance) {
            cb(err, instance);
        });
    };

    Frame.remoteMethod(
        'update_current_artwork', {
            description: 'Set the current artwork for this frame',
            accepts: {
                arg: 'currentArtworkId',
                type: 'number',
                required: true,
                http: {
                    source: 'path'
                }
            },
            http: {
                verb: 'put',
                path: '/current_artwork/:currentArtworkId'
            },
            isStatic: false,
            returns: {
                arg: 'frame',
                type: 'Object'
            }
        }
    );
};

<commit_msg>Fix type issue for current artwork endpoint<commit_after>var debug = require('debug')('openframe:apiserver:model:Frame'),
    loopback = require('loopback');

module.exports = function(Frame) {
    Frame.disableRemoteMethod('createChangeStream', true);

    // whenever a Frame model is saved, broadcast an update event
    Frame.observe('after save', function(ctx, next) {
        if (ctx.instance && Frame.app.pubsub) {
            debug('Saved %s#%s', ctx.Model.modelName, ctx.instance.id);
            if (ctx.isNewInstance) {
                debug('New Frame, publishing: /user/' + ctx.instance.ownerId + '/frame/new');
                Frame.app.pubsub.publish('/user/' + ctx.instance.ownerId + '/frame/new', ctx.instance.id);
            } else {
                debug('Existing Frame, publishing: /frame/' + ctx.instance.id + '/db_updated');
                debug(ctx.instance);
                Frame.findById(ctx.instance.id, { include: 'current_artwork' }, function(err, frame) {
                    debug(err, frame);
                    Frame.app.pubsub.publish('/frame/' + frame.id + '/db_updated', frame);
                });
            }
        }
        next();
    });

    // Ouch. Ow. Yowsers. Serisously?
    function removeManagers(frame, managers) {
        return new Promise((resolve, reject) => {
            frame.managers(function(err, current_managers) {
                if (current_managers.length) {
                    var count = 0,
                        total = current_managers.length;
                    current_managers.forEach(function(cur_man) {
                        if (managers.indexOf(cur_man.username) === -1) {
                            frame.managers.remove(cur_man, function(err) {
                                if (err) debug(err);
                                count++;
                                if (count === total) {
                                    // all who are no longer present in the new list have been removed
                                    resolve();
                                }
                            });
                        } else {
                            count++;
                            if (count === total) {
                                // all who are no longer present in the new list have been removed
                                resolve();
                            }
                        }
                    });
                } else {
                    // there are no current managers
                    resolve();
                }
            });
        });
    }

    // Painful painful painful -- so gross. Why loopback, why!?
    function addManagers(frame, managers) {
        var OpenframeUser = Frame.app.models.OpenframeUser;

        return new Promise((resolve, reject) => {
            OpenframeUser.find({ where: { username: { inq: managers }}}, function(err, users) {
                if (err) {
                    debug(err);
                }
                var count = 0,
                    total = users.length;
                if (total === 0) {
                    // no managers found by username, return frame including current managers
                    Frame.findById(frame.id, {include: 'managers'}, function(err, frame) {
                        debug(err, frame);
                        resolve(frame);
                    });
                } else {
                    // managers found by username, add them to frame, then
                    // return frame including current managers
                    // XXX: Unfortunately loopback doesn't seem to provide a way to batch
                    // update hasAndBelongsToMany relationships :/
                    users.forEach(function(user) {
                        frame.managers.add(user, function(err) {
                            count++;
                            if (count === total) {
                                Frame.findById(frame.id, {include: 'managers'}, function(err, frame) {
                                    debug(err, frame);
                                    resolve(frame);
                                });
                            }
                        });
                    });
                }

            });
        });
    }

    // Update managers by username
    //
    // XXX: This is incredibly ugly. Loopback doesn't provide a good way to update
    // this type of relationship all in one go, which makes it a huge messy pain. Given
    // time, I may fix this.
    Frame.prototype.update_managers_by_username = function(managers, cb) {
        debug(managers);
        var self = this;

        removeManagers(self, managers)
            .then(function() {
                addManagers(self, managers)
                    .then(function(frame) {
                        cb(null, frame);
                    })
                    .catch(debug);
            }).catch(debug);
    };

    // Expose update_managers_by_username remote method
    Frame.remoteMethod(
        'update_managers_by_username', {
            description: 'Add a related item by username for managers.',
            accepts: {
                arg: 'managers',
                type: 'array',
                http: {
                    source: 'body'
                }
            },
            http: {
                verb: 'put',
                path: '/managers/by_username'
            },
            isStatic: false,
            returns: {
                arg: 'frame',
                type: 'Object'
            }
        }
    );



    /**
     * Update the current artwork by artwork ID
     * @param  {String}   currentArtworkId
     * @param  {Function} callback
     */
    Frame.prototype.update_current_artwork = function(currentArtworkId, cb) {
        debug(currentArtworkId);
        var self = this;
        self.updateAttribute('currentArtworkId', currentArtworkId, function(err, instance) {
            cb(err, instance);
        });
    };

    Frame.remoteMethod(
        'update_current_artwork', {
            description: 'Set the current artwork for this frame',
            accepts: {
                arg: 'currentArtworkId',
                type: 'any',
                required: true,
                http: {
                    source: 'path'
                }
            },
            http: {
                verb: 'put',
                path: '/current_artwork/:currentArtworkId'
            },
            isStatic: false,
            returns: {
                arg: 'frame',
                type: 'Object'
            }
        }
    );
};


{'fraction_non_alphanumeric': 0.10302892967746809, 'fraction_numerical': 0.0006042752473751794, 'mean_word_length': 1.1344510720619054, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '78433', 'n_tokens_mistral': 3247, 'n_tokens_neox': 3057, 'n_words': 768}