mirror of
https://github.com/spacedeck/spacedeck-open.git
synced 2025-12-16 01:47:30 +01:00
initial commit.
This commit is contained in:
273
models/space.js
Normal file
273
models/space.js
Normal file
@@ -0,0 +1,273 @@
|
||||
'use strict';
|
||||
|
||||
var mongoose = require('mongoose');
|
||||
var Schema = mongoose.Schema;
|
||||
var async = require('async');
|
||||
var _ = require("underscore");
|
||||
var crypto = require('crypto');
|
||||
|
||||
module.exports.spaceSchema = Schema({
|
||||
name: {type: String, default: "New Space"},
|
||||
space_type: {type: String, default: "space"},
|
||||
|
||||
creator : { type: Schema.Types.ObjectId, ref: 'User' },
|
||||
parent_space_id: Schema.Types.ObjectId,
|
||||
|
||||
access_mode: {type: String, default: "private"}, // "public" || "private"
|
||||
password: String,
|
||||
edit_hash: String,
|
||||
edit_slug: String,
|
||||
editors_locking: Boolean,
|
||||
|
||||
thumbnail_uri: String,
|
||||
stats: {
|
||||
num_children: Number,
|
||||
total_spaces: Number,
|
||||
total_folders: Number,
|
||||
storage_bytes: Number,
|
||||
},
|
||||
|
||||
advanced: {
|
||||
type: {
|
||||
width: Number,
|
||||
height: Number,
|
||||
margin: Number,
|
||||
background_color: String,
|
||||
background_uri: String,
|
||||
background_repeat: Boolean,
|
||||
grid_size: Number,
|
||||
grid_divisions: Number,
|
||||
gutter: Number,
|
||||
columns: Number,
|
||||
column_max_width: Number,
|
||||
columns_responsive: Number,
|
||||
row_max_height: Number,
|
||||
padding_horz: Number,
|
||||
padding_vert: Number
|
||||
},
|
||||
default: {
|
||||
width: 200,
|
||||
height: 400,
|
||||
margin: 0,
|
||||
background_color: "rgba(255,255,255,1)"
|
||||
}
|
||||
},
|
||||
blocked_at: {type: Date, default: Date.now},
|
||||
created_at: {type: Date, default: Date.now},
|
||||
updated_at: {type: Date, default: Date.now},
|
||||
thumbnail_updated_at: {type: Date},
|
||||
thumbnail_url: String
|
||||
});
|
||||
|
||||
module.exports.spaceSchema.index({ creator: 1, parent_space_id: 1, created_at: 1, updated_at: 1, edit_hash: 1});
|
||||
module.exports.spaceSchema.statics.allForUser = function (user, callback) {
|
||||
return this.find({user_id: user_id}, callback);
|
||||
};
|
||||
|
||||
module.exports.spaceSchema.statics.getMemberships = function (err, callback) {
|
||||
callback(null, {});
|
||||
};
|
||||
|
||||
var getRecursiveSubspacesForSpace = (parentSpace, cb) => {
|
||||
if (parentSpace.space_type == "folder") {
|
||||
Space.find({
|
||||
"parent_space_id": parentSpace._id
|
||||
}).exec((err, subspaces) => {
|
||||
async.map(subspaces, (space, innerCb) => {
|
||||
getRecursiveSubspacesForSpace(space, (err, spaces) => {
|
||||
innerCb(err, spaces);
|
||||
});
|
||||
}, (err, subspaces) => {
|
||||
var flattenSubspaces = _.flatten(subspaces);
|
||||
flattenSubspaces.push(parentSpace);
|
||||
cb(null, flattenSubspaces);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
cb(null, [parentSpace]);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.spaceSchema.statics.getRecursiveSubspacesForSpace = getRecursiveSubspacesForSpace;
|
||||
|
||||
var roleMapping = {
|
||||
"none": 0,
|
||||
"viewer": 1,
|
||||
"editor": 2,
|
||||
"admin": 3
|
||||
}
|
||||
|
||||
module.exports.spaceSchema.statics.roleInSpace = (originalSpace, user, cb) => {
|
||||
if (user.home_folder_id.toString() === originalSpace._id.toString()) {
|
||||
cb(null, "admin");
|
||||
return;
|
||||
}
|
||||
|
||||
if (originalSpace.creator) {
|
||||
if (originalSpace.creator._id.toString() === user._id.toString()) {
|
||||
cb(null, "admin");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var findMembershipsForSpace = function(space, allMemberships, prevRole) {
|
||||
Membership.find({
|
||||
"space": space._id
|
||||
}, (err, parentMemberships) => {
|
||||
var currentMemberships = parentMemberships.concat(allMemberships);
|
||||
|
||||
if (space.parent_space_id) {
|
||||
Space.findOne({
|
||||
"_id": space.parent_space_id
|
||||
}, function(err, parentSpace) {
|
||||
|
||||
var role = prevRole;
|
||||
if(role == "none"){
|
||||
if(originalSpace.access_mode == "public") {
|
||||
role = "viewer";
|
||||
}
|
||||
}
|
||||
|
||||
findMembershipsForSpace(parentSpace, currentMemberships, role);
|
||||
});
|
||||
} else {
|
||||
// reached the top
|
||||
var role = prevRole;
|
||||
space.memberships = currentMemberships;
|
||||
currentMemberships.forEach(function(m, i) {
|
||||
if (m.user && m.user.equals(user._id)) {
|
||||
if (m.role != null) {
|
||||
if (roleMapping[m.role] > roleMapping[role]) {
|
||||
role = m.role;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
cb(err, role);
|
||||
}
|
||||
});
|
||||
};
|
||||
findMembershipsForSpace(originalSpace, [], "none");
|
||||
}
|
||||
|
||||
module.exports.spaceSchema.statics.recursiveDelete = (space, cb) => {
|
||||
space.remove(function(err) {
|
||||
|
||||
Action.remove({
|
||||
space: space
|
||||
}, function(err) {
|
||||
if (err)
|
||||
console.error("removed actions for space: ", err);
|
||||
});
|
||||
|
||||
Membership.remove({
|
||||
space: space
|
||||
}, function(err) {
|
||||
if (err)
|
||||
console.error("removed memberships for space: ", err);
|
||||
});
|
||||
|
||||
if (space.space_type === "folder") {
|
||||
Space
|
||||
.find({
|
||||
parent_space_id: space._id
|
||||
})
|
||||
.exec(function(err, spaces) {
|
||||
async.eachLimit(spaces, 10, function(subSpace, innerCb) {
|
||||
module.exports.spaceSchema.statics.recursiveDelete(subSpace, function(err) {
|
||||
innerCb(err);
|
||||
});
|
||||
}, function(err) {
|
||||
cb(err);
|
||||
});
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
Artifact.find({
|
||||
space_id: space._id
|
||||
}, function(err, artifacts) {
|
||||
if (err) cb(err);
|
||||
else {
|
||||
async.eachLimit(artifacts, 20, function(a, innerCb) {
|
||||
a.remove(function(err) {
|
||||
innerCb(null, a);
|
||||
});
|
||||
}, function(err) {
|
||||
cb(err);
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var duplicateRecursiveSpace = (space, user, depth, cb, newParentSpace) => {
|
||||
var newSpace = new Space(space);
|
||||
newSpace._id = mongoose.Types.ObjectId();
|
||||
|
||||
if (newParentSpace) {
|
||||
newSpace.parent_space_id = newParentSpace._id;
|
||||
} else {
|
||||
newSpace.name = newSpace.name + " (b)";
|
||||
}
|
||||
|
||||
newSpace.creator = user;
|
||||
newSpace.created_at = new Date();
|
||||
newSpace.updated_at = new Date();
|
||||
|
||||
if (newSpace.space_type === "space") {
|
||||
newSpace.edit_hash = crypto.randomBytes(64).toString('hex').substring(0, 7);
|
||||
}
|
||||
|
||||
newSpace.save(function(err) {
|
||||
|
||||
if (newSpace.space_type === "folder" && depth < 10) {
|
||||
|
||||
Space
|
||||
.find({
|
||||
parent_space_id: space._id
|
||||
})
|
||||
.exec(function(err, spaces) {
|
||||
async.eachLimit(spaces, 10, function(subSpace, innerCb) {
|
||||
|
||||
duplicateRecursiveSpace(subSpace, user, ++depth, function(err, newSubSpace) {
|
||||
innerCb(err, newSubSpace);
|
||||
}, newSpace);
|
||||
|
||||
}, function(err, allNewSubspaces) {
|
||||
cb(err, newSpace);
|
||||
});
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
Artifact.find({
|
||||
space_id: space._id
|
||||
}, function(err, artifacts) {
|
||||
if (err) innerCb(err);
|
||||
else {
|
||||
async.eachLimit(artifacts, 20, function(a, innerCb) {
|
||||
var newArtifact = new Artifact(a);
|
||||
newArtifact._id = mongoose.Types.ObjectId();
|
||||
newArtifact.space_id = newSpace._id;
|
||||
newArtifact.created_at = new Date();
|
||||
newArtifact.updated_at = new Date();
|
||||
|
||||
newArtifact.save(function(err) {
|
||||
innerCb(null, newArtifact);
|
||||
});
|
||||
|
||||
}, function(err, allNewArtifacts) {
|
||||
cb(err, newSpace);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.spaceSchema.statics.duplicateSpace = duplicateRecursiveSpace;
|
||||
Reference in New Issue
Block a user