Initial databankerisation of profile [#331]

* Stats functionality disabled until completion of SamStudio8/dbot-stats#98
* Profile grid currently only works with dbType set to memory
* Merge user functionality temporarily disabled
This commit is contained in:
Sam Nicholls 2013-04-20 22:51:36 +01:00
parent bd2d0a8953
commit ab0a110a8e
8 changed files with 150 additions and 144 deletions

View File

@ -4,64 +4,77 @@ var api = function(dbot) {
return {
/**
* Create a profile for a new primary user on a given server.
* If the server does not already exist, create it.
* Create a new profile for a given "databanked" user.
* Typically only called as a hook to the new_user emit event.
* TODO(@samstudio8) Migrate to internalAPI
*/
"createProfile": function(server, primary){
var primaryLower = primary.toLowerCase();
if(!_.has(this.profiles, server)){
this.profiles[server] = {};
}
if(!_.has(this.profiles[server], primaryLower)){
this.profiles[server][primaryLower] = {
"profile": {},
"preferences": {}
};
this.profiles[server][primaryLower].profile.primary = primary;
}
// Ensure all profiles have the keys specified by config.json
//TODO(samstudio8) Currently only handles "top-level"
_.defaults(this.profiles[server][primaryLower].profile, this.config.schema.profile);
_.defaults(this.profiles[server][primaryLower].preferences, this.config.schema.preferences);
},
/**
* Given a server and "new" alias, resolve this alias to the user's
* new primary name and move profile data pertaining to the alias to
* the new primary name.
*/
'renameProfile': function(server, alias){
if(!_.has(this.profiles, server)) return;
var profiles = dbot.db.profiles[server];
if(_.has(profiles, alias)){
var primary = dbot.api.users.resolveUser(server, alias, true);
var primaryLower = primary.toLowerCase();
alias = alias.trim().toLowerCase();
profiles[primaryLower] = profiles[alias];
profiles[primaryLower].profile.primary = primary;
delete profiles[alias];
"createProfile": function(user, callback){
if(user){
this.db.create('profiles', user.id, {
'id': user.id,
'profile': dbot.config.profile.schema.profile,
'preferences': dbot.config.profile.schema.preferences
}, function(err, result){
if(err){
console.log(err);
}
});
}
},
//TODO(samstudio8) Merge Profiles
'mergeProfile': function(server, nick, callback){
console.log("mergeProfile not implemented");
},
/**
* Given a server and a primary username which has been converted to a
* secondary alias find and remove the profile for the alias.
*/
'mergeProfile': function(server, mergeFromPrimary){
if(!_.has(this.profiles, server)) return;
var profiles = dbot.db.profiles[server];
'getProfile': function(server, nick, callback){
dbot.api.users.resolveUser(server, nick, function(user){
if(user){
this.db.read('profiles', user.id, function(err, profile){
callback(false, user, profile);
});
}
else{
callback(true, null, null);
}
}.bind(this));
},
mergeFromPrimary = mergeFromPrimary.toLowerCase();
var mergeToPrimary = dbot.api.users.resolveUser(server, mergeFromPrimary, true).toLowerCase();
if(!_.has(profiles, mergeToPrimary)
|| !_.has(profiles, mergeFromPrimary)) return;
'getAllProfiles': function(callback){
var profiles = [];
this.db.scan('profiles', function(profile){
profiles.push(profile);
}, function(err){
if(!err){
callback(profiles);
}
else{
console.log(err);
}
});
},
// Remove the profile of the alias
delete profiles[mergeFromPrimary];
'setProperty': function(server, nick, field, value, callback){
this.api.getProfile(server, nick, function(err, user, profile){
if(!err){
profile.profile[field] = value;
this.db.save('profiles', user.id, profile, function(err){
if(!err){
callback("Ok!");
}
});
}
}.bind(this));
},
'getProperty': function(server, nick, field, callback){
this.api.getProfile(server, nick, function(err, user, profile){
if(!err){
if(profile.profile[field]){
callback(profile.profile[field]);
}
}
}.bind(this));
},
}
};

View File

@ -5,23 +5,10 @@ var commands = function(dbot){
"~getprop": function(event){
if(event.params[1]){
var primary = dbot.api.users.resolveUser(event.server, event.user);
var res = dbot.db.profiles[event.server][primary.toLowerCase()].profile[event.params[1]];
if(res){
event.reply(res);
}
else{
event.reply("Nope.");
}
}
},
"~setprop": function(event){
if(event.input[1] && event.input[2]){
if(_.has(this.config.schema.profile, event.input[1])){
var primary = dbot.api.users.resolveUser(event.server, event.user);
dbot.db.profiles[event.server][primary.toLowerCase()].profile[event.input[1]] = event.input[2];
event.reply("Property set, maybe?");
if(_.has(this.config.schema.profile, event.params[1])){
this.api.getProperty(event.server, event.user, event.params[1], function(reply){
event.reply(reply);
});
}
else{
event.reply("Invalid property. Go home.");
@ -29,23 +16,18 @@ var commands = function(dbot){
}
},
"~profile": function(event){
if(event.params[1]){
var primary = dbot.api.users.resolveUser(event.server, event.params[1]);
if(_.has(dbot.db.profiles[event.server], primary.toLowerCase())){
event.reply(dbot.api.web.getUrl("profile/"+event.server+"/"+primary.toLowerCase()));
"~setprop": function(event){
if(event.input[1] && event.input[2]){
if(_.has(this.config.schema.profile, event.input[1])){
this.api.setProperty(event.server, event.user, event.input[1], event.input[2], function(reply){
event.reply(reply);
});
}
else{
event.reply("No profile found for "+event.params[1]);
event.reply("Invalid property. Go home.");
}
}
else{
event.message = '~profile ' + event.user;
event.action = 'PRIVMSG';
event.params = event.message.split(' ');
dbot.instance.emit(event);
}
}
},
};
commands['~setprop'].regex = [/~setprop ([^ ]+) (.+)/, 3];

View File

@ -1,6 +1,6 @@
{
"ignorable": false,
"dbKeys": [ "profiles" ],
"dbType": "memory",
"help": "https://github.com/reality/depressionbot/blob/master/modules/profile/README.md",
"schema": {
"profile": {

View File

@ -5,58 +5,80 @@ var pages = function(dbot) {
return {
'/profile/:connection/:user': function(req, res) {
var connection = req.params.connection;
var user = dbot.cleanNick(req.params.user);
var nick = req.params.user;
var primary = dbot.api.users.resolveUser(connection, user, true);
//var profile = dbot.api.profile.getProfile(primary);
var profile = dbot.db.profiles[connection][primary.toLowerCase()].profile;
var stats = dbot.api.stats.getUserChansStats(connection, primary.toLowerCase(), [
"lines", "words", "lincent", "wpl", "in_mentions"]
);
dbot.api.users.resolveUser(connection, nick, function(user){
if(user){
dbot.api.profile.getProfile(connection, user.primaryNick, function(err, user, profile){
if(!err){
var stats = [];
res.render('profile', {
'name': dbot.config.name,
'connection': connection,
'primary': primary,
'profile': profile,
'stats': stats.channels,
/*TODO(@samstudio8)
* stats functionality currently disabled as it has not been databanked
*/
//var stats = dbot.api.stats.getUserChansStats(connection, user.primaryNick, [
// "lines", "words", "lincent", "wpl", "in_mentions"]
//);
res.render('profile', {
'name': dbot.config.name,
'connection': connection,
'primary': user.primaryNick,
'profile': profile.profile,
'stats': stats.channels,
});
}
else{
res.render('error', {
});
}
});
}
else{
res.render('not_found', {
});
}
});
},
'/profile/:connection': function(req, res) {
var connection = req.params.connection;
var profiles = dbot.db.profiles[connection];
dbot.api.profile.getAllProfiles(function(profiles){
var thumbnails = [];
_.each(profiles, function(profile){
var nick = dbot.api.users.getUser(profile.id, function(user){
if(user){
// TODO: Clean up
_.each(profiles, function(profile) {
if(_.has(dbot.db.quoteArrs, profile.profile.primary) && !profile.profile.avatar) {
var category = dbot.db.quoteArrs[profile.profile.primary];
var avatar = _.find(category, function(quote) {
return quote.match(/(\.jpg|\.png|\.jpeg)$/i);
/*TODO(@tmenari / @samstudio8)
* if username has a quote array and no avatar:
* search their quote array for a jpg, png, jpeg or gif
* set this as their new avatar
*/
if(profile.profile.avatar){
thumbnails.push({
"avatar": profile.profile.avatar,
"nick": user.primaryNick
});
}
}
});
if(avatar) profile.profile.avatar = avatar;
}
});
});
var nicks = [];
for (var p in profiles) {
if (profiles.hasOwnProperty(p) && profiles[p].profile.avatar) {
nicks.push(p);
}
}
nicks.sort(function(a, b) {
var x = profiles[a].profile.primary.toLowerCase();
var y = profiles[b].profile.primary.toLowerCase();
if(x > y) return 1;
if(x < y) return -1;
return 0;
});
process.nextTick(function(){
thumbnails.sort(function(a, b) {
var x = a.nick.toLowerCase();
var y = b.nick.toLowerCase();
if(x > y) return 1;
if(x < y) return -1;
return 0;
});
res.render('profile_grid', {
'name': dbot.config.name,
'connection': connection,
'nicks': nicks,
'profiles': profiles,
res.render('profile_grid', {
'name': dbot.config.name,
'connection': req.params.connection,
'thumbnails': thumbnails,
});
});
});
}
}

View File

@ -2,27 +2,14 @@ var _ = require('underscore')._;
var profile = function(dbot) {
this.profiles = dbot.db.profiles;
/**
* Iterate over known user profiles and ensure they contain all the
* required properties as defined in the configuation.
*/
this.onLoad = function(){
var api = this.api;
var schema = this.config.schema;
// Ensure all known users have a profile
_.each(dbot.api.users.getAllUsers(), function(server, serverName){
_.each(server, function(primary, primaryi){
api.createProfile(serverName, primary);
});
});
dbot.save();
// Add API Hooks
dbot.api.command.addHook('~setaliasparent', this.api.renameProfile);
dbot.api.command.addHook('~mergeusers', this.api.mergeProfile);
//TODO(@samstudio8) Profile Merging
//dbot.api.command.addHook('~mergeusers', this.api.mergeProfile);
dbot.api.event.addHook('new_user', this.api.createProfile);
};
};

1
views/profile/error.jade Normal file
View File

@ -0,0 +1 @@
h1 Error

View File

@ -0,0 +1 @@
h1 Not Found

View File

@ -18,9 +18,9 @@ block content
a(href='../connections') &laquo; Connections
ul.thumbnails
each nick in nicks
each thumbnail in thumbnails
li.span2
a.thumbnail(href='/profile/'+connection+'/'+encodeURIComponent(nick))
a.thumbnail(href='/profile/'+connection+'/'+encodeURIComponent(thumbnail.nick))
div.imgwrap
img(src="#{profiles[nick].profile.avatar}", alt="#{profiles[nick].profile.primary}'s photo")
span.nicks #{profiles[nick].profile.primary}
img(src="#{thumbnail.avatar}", alt="#{thumbnail.nick}'s photo")
span.nicks #{thumbnail.nick}