221 lines
8.9 KiB
JavaScript
221 lines
8.9 KiB
JavaScript
"use strict";
|
|
|
|
const DatabaseManager = (function(){
|
|
|
|
const DatabaseManager = function(judge_pole){
|
|
|
|
const self = this;
|
|
let data = {
|
|
users : [],
|
|
projects : [],
|
|
criteria : [],
|
|
votes : {} // { project_id: { user_id: { criterion_name: score } } }
|
|
};
|
|
|
|
const constructor = () => {
|
|
// Inicializar criterios por defecto si no existen
|
|
const default_crit = judge_pole.settings.get("default_criteria", null, []);
|
|
default_crit.forEach(crit => self.add_criterion(crit));
|
|
|
|
// Carga de base de datos externa inyectada
|
|
if(typeof database != "undefined" && typeof database == "string"){
|
|
self.import_base64(database);
|
|
}
|
|
};
|
|
|
|
this.get_data = () => data;
|
|
|
|
this.add_criterion = (criterion_name) => {
|
|
criterion_name = ("" + criterion_name).trim();
|
|
if(criterion_name && !data.criteria.includes(criterion_name)){
|
|
data.criteria.push(criterion_name);
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
this.update_criterion = (old_name, new_name) => {
|
|
old_name = ("" + old_name).trim();
|
|
new_name = ("" + new_name).trim();
|
|
|
|
if(!new_name || old_name === new_name) return false;
|
|
|
|
const index = data.criteria.indexOf(old_name);
|
|
if(index === -1) return false;
|
|
|
|
// Reemplazar en la lista maestra
|
|
data.criteria[index] = new_name;
|
|
|
|
// Propagar en cascada en todos los votos existentes
|
|
Object.keys(data.votes).forEach(project_id => {
|
|
const project_votes = data.votes[project_id];
|
|
if(project_votes){
|
|
Object.keys(project_votes).forEach(user_id => {
|
|
if(project_votes[user_id] && project_votes[user_id][old_name] !== undefined){
|
|
project_votes[user_id][new_name] = project_votes[user_id][old_name];
|
|
delete project_votes[user_id][old_name];
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
return true;
|
|
};
|
|
|
|
this.delete_criterion = (criterion_name) => {
|
|
criterion_name = ("" + criterion_name).trim();
|
|
const initial_len = data.criteria.length;
|
|
data.criteria = data.criteria.filter(c => c !== criterion_name);
|
|
|
|
if(data.criteria.length !== initial_len){
|
|
// Purgar el criterio de todos los votos guardados
|
|
Object.keys(data.votes).forEach(project_id => {
|
|
const project_votes = data.votes[project_id];
|
|
if(project_votes){
|
|
Object.keys(project_votes).forEach(user_id => {
|
|
if(project_votes[user_id] && project_votes[user_id][criterion_name] !== undefined){
|
|
delete project_votes[user_id][criterion_name];
|
|
}
|
|
});
|
|
}
|
|
});
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
this.save_votes = (project_id, vote_package) => {
|
|
// vote_package: { scores, judge_weights, criteria_weights }
|
|
data.votes[project_id] = vote_package;
|
|
};
|
|
|
|
this.export_base64 = () => {
|
|
const json_string = JSON.stringify(data, null, 4);
|
|
return btoa(unescape(encodeURIComponent(json_string)));
|
|
};
|
|
|
|
this.import_base64 = (base64_string) => {
|
|
try {
|
|
const json_string = decodeURIComponent(escape(atob(base64_string.trim())));
|
|
data = JSON.parse(json_string);
|
|
return true;
|
|
} catch(error) {
|
|
console.error("Error al importar Base64:", error);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
this.delete_user = (user_id) => {
|
|
const initial_length = data.users.length;
|
|
data.users = data.users.filter(u => u.id !== user_id);
|
|
|
|
if(data.users.length !== initial_length){
|
|
// Limpieza de proyectos huérfanos asociados a este usuario
|
|
const removed_project_ids = data.projects
|
|
.filter(p => p.user_id === user_id)
|
|
.map(p => p.id);
|
|
|
|
data.projects = data.projects.filter(p => p.user_id !== user_id);
|
|
|
|
// Limpieza de votos del usuario o de proyectos eliminados
|
|
removed_project_ids.forEach(p_id => {
|
|
delete data.votes[p_id];
|
|
});
|
|
|
|
Object.keys(data.votes).forEach(p_id => {
|
|
if(data.votes[p_id] && data.votes[p_id][user_id]){
|
|
delete data.votes[p_id][user_id];
|
|
}
|
|
});
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
this.add_user = (user_data) => {
|
|
const now = new Date().toISOString();
|
|
const user = {
|
|
id : "usr_" + Date.now() + "_" + Math.floor(Math.random() * 1000),
|
|
type : user_data.type || "human", // "human" | "ai"
|
|
nick : user_data.nick || "Anon",
|
|
password : user_data.password ? user_data.password.trim() : "",
|
|
description : user_data.description || "",
|
|
avatar : user_data.avatar || "",
|
|
links : user_data.links || [],
|
|
created_at : now,
|
|
updated_at : now
|
|
};
|
|
data.users.push(user);
|
|
return user;
|
|
};
|
|
|
|
this.update_user = (user_id, updated_fields) => {
|
|
const user = data.users.find(u => u.id === user_id);
|
|
if(!user) return null;
|
|
|
|
user.type = updated_fields.type !== undefined ? updated_fields.type : (user.type || "human");
|
|
user.nick = updated_fields.nick !== undefined ? updated_fields.nick : user.nick;
|
|
user.password = updated_fields.password !== undefined ? updated_fields.password.trim() : (user.password || "");
|
|
user.description = updated_fields.description !== undefined ? updated_fields.description : user.description;
|
|
user.avatar = updated_fields.avatar !== undefined ? updated_fields.avatar : user.avatar;
|
|
user.links = updated_fields.links !== undefined ? updated_fields.links : user.links;
|
|
user.updated_at = new Date().toISOString();
|
|
|
|
return user;
|
|
};
|
|
|
|
this.add_project = (project_data) => {
|
|
const now = new Date().toISOString();
|
|
const project = {
|
|
id : "prj_" + Date.now() + "_" + Math.floor(Math.random() * 1000),
|
|
user_ids : project_data.user_ids || (project_data.user_id ? [project_data.user_id] : []),
|
|
name : project_data.name,
|
|
description : project_data.description || "",
|
|
avatar : project_data.avatar || "",
|
|
tags : project_data.tags || [],
|
|
technologies : project_data.technologies || [],
|
|
links : project_data.links || [],
|
|
created_at : now,
|
|
updated_at : now
|
|
};
|
|
data.projects.push(project);
|
|
return project;
|
|
};
|
|
|
|
this.update_project = (project_id, updated_fields) => {
|
|
const project = data.projects.find(p => p.id === project_id);
|
|
if(!project) return null;
|
|
|
|
project.user_ids = updated_fields.user_ids !== undefined ? updated_fields.user_ids : (project.user_ids || (project.user_id ? [project.user_id] : []));
|
|
project.name = updated_fields.name !== undefined ? updated_fields.name : project.name;
|
|
project.description = updated_fields.description !== undefined ? updated_fields.description : project.description;
|
|
project.avatar = updated_fields.avatar !== undefined ? updated_fields.avatar : project.avatar;
|
|
project.tags = updated_fields.tags !== undefined ? updated_fields.tags : project.tags;
|
|
project.technologies = updated_fields.technologies !== undefined ? updated_fields.technologies : project.technologies;
|
|
project.links = updated_fields.links !== undefined ? updated_fields.links : project.links;
|
|
project.updated_at = new Date().toISOString();
|
|
|
|
return project;
|
|
};
|
|
|
|
this.delete_project = (project_id) => {
|
|
const initial_length = data.projects.length;
|
|
data.projects = data.projects.filter(p => p.id !== project_id);
|
|
|
|
if(data.projects.length !== initial_length){
|
|
// Limpieza de las puntuaciones asociadas al proyecto eliminado
|
|
if(data.votes[project_id]){
|
|
delete data.votes[project_id];
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
constructor();
|
|
|
|
};
|
|
|
|
return DatabaseManager;
|
|
})(); |