Spaces:
Running
Running
const mongoose = require('mongoose'); | |
const logger = require('./logger'); | |
const bcrypt = require('bcrypt'); | |
const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://localhost:27017/stremio-manager'; | |
// Connection options | |
const options = { | |
useNewUrlParser: true, | |
useUnifiedTopology: true, | |
serverSelectionTimeoutMS: 5000, | |
socketTimeoutMS: 45000, | |
}; | |
// Create connection | |
let db; | |
async function connectDB() { | |
try { | |
if (!db) { | |
db = await mongoose.connect(MONGODB_URI, options); | |
logger.info('MongoDB connected successfully'); | |
} | |
return db; | |
} catch (error) { | |
logger.error('MongoDB connection error:', error); | |
throw error; | |
} | |
} | |
// Initialize connection before starting server | |
async function initializeDB() { | |
await connectDB(); | |
} | |
mongoose.connection.on('error', err => { | |
logger.error('MongoDB error:', err); | |
}); | |
mongoose.connection.on('disconnected', () => { | |
logger.warn('MongoDB disconnected. Attempting to reconnect...'); | |
connectDB(); | |
}); | |
// Define schemas | |
const userSchema = new mongoose.Schema({ | |
email: { type: String, required: true, unique: true }, | |
password: { type: String, required: true }, | |
lastSync: Date, | |
managedBy: { type: String, required: true } | |
}); | |
// Hash the password before saving it | |
userSchema.pre('save', async function(next) { | |
if (this.isModified('password')) { | |
this.password = await bcrypt.hash(this.password, 10); | |
} | |
next(); | |
}); | |
const addonSchema = new mongoose.Schema({ | |
transportUrl: { type: String, required: true }, | |
transportName: { type: String, default: 'http' }, | |
manifest: { | |
id: String, | |
name: String, | |
version: String, | |
description: String, | |
logo: String, | |
icon: String | |
}, | |
flags: { type: Map, of: Boolean }, | |
userEmail: { type: String, required: true } | |
}); | |
const catalogSchema = new mongoose.Schema({ | |
userEmail: { type: String, required: true }, | |
addons: [{ | |
transportUrl: String, | |
transportName: String, | |
manifest: { | |
id: String, | |
name: String, | |
version: String, | |
description: String, | |
logo: String, | |
icon: String | |
}, | |
flags: { type: Map, of: Boolean } | |
}] | |
}); | |
// Create models | |
const User = mongoose.model('User', userSchema); | |
const Addon = mongoose.model('Addon', addonSchema); | |
const Catalog = mongoose.model('Catalog', catalogSchema); | |
// Database helper functions | |
async function ensureUserDatabases(email) { | |
const catalog = await Catalog.findOne({ userEmail: email }); | |
if (!catalog) { | |
await Catalog.create({ userEmail: email, addons: [] }); | |
} | |
} | |
async function readDatabase(email) { | |
const addons = await Addon.find({ userEmail: email }); | |
return addons; | |
} | |
async function writeDatabase(email, data) { | |
await Addon.deleteMany({ userEmail: email }); | |
if (data.length > 0) { | |
const addonsWithUser = data.map(addon => ({ ...addon, userEmail: email })); | |
await Addon.insertMany(addonsWithUser); | |
} | |
logger.debug('Database updated successfully'); | |
} | |
async function readUsersDatabase(email) { | |
const users = await User.find({ managedBy: email }); | |
return users.map(user => ({ | |
email: user.email, | |
password: user.password, | |
lastSync: user.lastSync | |
})); | |
} | |
async function writeUsersDatabase(email, data) { | |
await User.deleteMany({ managedBy: email }); | |
if (data.length > 0) { | |
const usersWithManager = data.map(user => ({ | |
...user, | |
managedBy: email | |
})); | |
await User.insertMany(usersWithManager); | |
} | |
logger.debug('Users database updated successfully'); | |
} | |
async function writeCatalog(email, catalogs) { | |
await Catalog.findOneAndUpdate( | |
{ userEmail: email }, | |
{ addons: catalogs }, | |
{ upsert: true } | |
); | |
} | |
async function readCatalog(email) { | |
const catalog = await Catalog.findOne({ userEmail: email }); | |
return catalog ? catalog.addons : []; | |
} | |
module.exports = { | |
connectDB, | |
initializeDB, | |
ensureUserDatabases, | |
readDatabase, | |
writeDatabase, | |
readUsersDatabase, | |
writeUsersDatabase, | |
writeCatalog, | |
readCatalog, | |
models: { | |
User, | |
Addon, | |
Catalog | |
} | |
}; | |