TransHub_backend / models /Subtitle.js
linguabot's picture
Upload folder using huggingface_hub
da819ac verified
const mongoose = require('mongoose');
const subtitleSchema = new mongoose.Schema({
segmentId: {
type: Number,
required: true,
unique: true
},
startTime: {
type: String,
required: true,
validate: {
validator: function(v) {
// Validate time format: HH:MM:SS,mmm
return /^\d{2}:\d{2}:\d{2},\d{3}$/.test(v);
},
message: 'Start time must be in format HH:MM:SS,mmm'
}
},
endTime: {
type: String,
required: true,
validate: {
validator: function(v) {
// Validate time format: HH:MM:SS,mmm
return /^\d{2}:\d{2}:\d{2},\d{3}$/.test(v);
},
message: 'End time must be in format HH:MM:SS,mmm'
}
},
duration: {
type: String,
required: true
},
englishText: {
type: String,
required: true,
trim: true
},
chineseTranslation: {
type: String,
default: '',
trim: true
},
isProtected: {
type: Boolean,
default: false
},
protectedReason: {
type: String
},
lastModified: {
type: Date,
default: Date.now
},
modificationHistory: [{
action: {
type: String,
required: true
},
timestamp: {
type: Date,
default: Date.now
},
reason: {
type: String
}
}]
}, {
timestamps: true
});
// Index for efficient queries
subtitleSchema.index({ segmentId: 1 });
subtitleSchema.index({ startTime: 1 });
subtitleSchema.index({ isProtected: 1 });
// Virtual for calculating duration in seconds
subtitleSchema.virtual('durationInSeconds').get(function() {
const start = this.parseTimeToSeconds(this.startTime);
const end = this.parseTimeToSeconds(this.endTime);
return end - start;
});
// Method to parse time string to seconds
subtitleSchema.methods.parseTimeToSeconds = function(timeString) {
const parts = timeString.split(':');
const seconds = parseInt(parts[2].split(',')[0]);
const minutes = parseInt(parts[1]);
const hours = parseInt(parts[0]);
return hours * 3600 + minutes * 60 + seconds;
};
// Static method to get all subtitles ordered by segment ID
subtitleSchema.statics.getAllOrdered = function() {
return this.find().sort({ segmentId: 1 });
};
// Static method to get protected subtitles
subtitleSchema.statics.getProtected = function() {
return this.find({ isProtected: true });
};
// Static method to update subtitle safely
subtitleSchema.statics.safeUpdate = function(segmentId, updateData) {
return this.findOneAndUpdate(
{ segmentId: segmentId },
{
...updateData,
lastModified: new Date(),
$push: {
modificationHistory: {
action: 'update',
timestamp: new Date(),
reason: updateData.reason || 'Manual update'
}
}
},
{ new: true, runValidators: true }
);
};
// Static method to protect subtitle
subtitleSchema.statics.protectSubtitle = function(segmentId, reason) {
return this.findOneAndUpdate(
{ segmentId: segmentId },
{
isProtected: true,
protectedReason: reason,
lastModified: new Date(),
$push: {
modificationHistory: {
action: 'protect',
timestamp: new Date(),
reason: reason
}
}
},
{ new: true }
);
};
// Static method to unlock subtitle
subtitleSchema.statics.unlockSubtitle = function(segmentId, unlockKey) {
// In a real implementation, you'd verify the unlock key
if (unlockKey !== 'ADMIN_UNLOCK_KEY_2024') {
throw new Error('Invalid unlock key');
}
return this.findOneAndUpdate(
{ segmentId: segmentId },
{
isProtected: false,
protectedReason: null,
lastModified: new Date(),
$push: {
modificationHistory: {
action: 'unlock',
timestamp: new Date(),
reason: 'Admin unlock'
}
}
},
{ new: true }
);
};
module.exports = mongoose.model('Subtitle', subtitleSchema);