from datetime import datetime from app import db class Set(db.Model): """Model for LEGO sets.""" __tablename__ = 'sets' id = db.Column(db.Integer, primary_key=True) set_number = db.Column(db.String(20), unique=True, nullable=False, index=True) set_name = db.Column(db.String(200), nullable=False) theme = db.Column(db.String(100), nullable=False, index=True) year_released = db.Column(db.Integer, nullable=False, index=True) piece_count = db.Column(db.Integer) # MOC (My Own Creation) support is_moc = db.Column(db.Boolean, default=False, nullable=False, index=True) moc_designer = db.Column(db.String(100), nullable=True) # Designer/creator name moc_description = db.Column(db.Text, nullable=True) # Detailed description # Brickset integration brickset_id = db.Column(db.Integer, unique=True, nullable=True) image_url = db.Column(db.String(500)) # External URL (Brickset, etc.) cover_image = db.Column(db.String(500)) # Uploaded cover image path # Metadata user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) updated_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow, onupdate=datetime.utcnow) # Relationships instructions = db.relationship('Instruction', backref='set', lazy='dynamic', cascade='all, delete-orphan') extra_files = db.relationship('ExtraFile', back_populates='lego_set', lazy='dynamic', cascade='all, delete-orphan', order_by='ExtraFile.uploaded_at.desc()') def __repr__(self): return f'' def get_image(self): """Get the best available image (uploaded cover takes priority).""" if self.cover_image: # Ensure forward slashes for web URLs clean_path = self.cover_image.replace('\\', '/') return f'/static/uploads/{clean_path}' return self.image_url @property def has_cover_image(self): """Check if set has an uploaded cover image.""" return bool(self.cover_image) @property def cover_image_url(self): """Get the uploaded cover image URL.""" if self.cover_image: clean_path = self.cover_image.replace('\\', '/') return f'/static/uploads/{clean_path}' return None def to_dict(self): """Convert set to dictionary.""" return { 'id': self.id, 'set_number': self.set_number, 'set_name': self.set_name, 'theme': self.theme, 'year_released': self.year_released, 'piece_count': self.piece_count, 'image_url': self.image_url, 'is_moc': self.is_moc, 'moc_designer': self.moc_designer, 'moc_description': self.moc_description, 'instruction_count': self.instructions.count(), 'created_at': self.created_at.isoformat(), 'updated_at': self.updated_at.isoformat() } @property def instruction_files(self): """Get all instruction files for this set.""" return self.instructions.order_by(Instruction.page_number).all() @property def pdf_instructions(self): """Get only PDF instructions.""" return self.instructions.filter_by(file_type='PDF').all() @property def image_instructions(self): """Get only image instructions.""" return self.instructions.filter_by(file_type='IMAGE').order_by( Instruction.page_number).all() # Import here to avoid circular imports from app.models.instruction import Instruction