Initial commit - LEGO Instructions Manager v1.5.0
This commit is contained in:
123
app/models/extra_file.py
Normal file
123
app/models/extra_file.py
Normal file
@@ -0,0 +1,123 @@
|
||||
from datetime import datetime
|
||||
from app import db
|
||||
|
||||
|
||||
class ExtraFile(db.Model):
|
||||
"""Model for extra files attached to sets (BrickLink XML, Stud.io, box art, etc)."""
|
||||
|
||||
__tablename__ = 'extra_files'
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
set_id = db.Column(db.Integer, db.ForeignKey('sets.id', ondelete='CASCADE'), nullable=False)
|
||||
|
||||
# File information
|
||||
file_name = db.Column(db.String(255), nullable=False)
|
||||
original_filename = db.Column(db.String(255), nullable=False) # Original name before hashing
|
||||
file_path = db.Column(db.String(500), nullable=False)
|
||||
file_type = db.Column(db.String(50), nullable=False) # Extension
|
||||
file_size = db.Column(db.Integer, nullable=False) # Size in bytes
|
||||
|
||||
# Metadata
|
||||
description = db.Column(db.Text)
|
||||
category = db.Column(db.String(50)) # 'bricklink', 'studio', 'box_art', 'document', 'photo', 'other'
|
||||
|
||||
# Tracking
|
||||
uploaded_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
|
||||
uploaded_by = db.Column(db.Integer, db.ForeignKey('users.id'))
|
||||
|
||||
# Relationships
|
||||
lego_set = db.relationship('Set', back_populates='extra_files')
|
||||
uploader = db.relationship('User', backref='uploaded_files')
|
||||
|
||||
def __repr__(self):
|
||||
return f'<ExtraFile {self.file_name} for Set {self.set_id}>'
|
||||
|
||||
@property
|
||||
def file_size_formatted(self):
|
||||
"""Return human-readable file size."""
|
||||
size = self.file_size
|
||||
for unit in ['B', 'KB', 'MB', 'GB']:
|
||||
if size < 1024.0:
|
||||
return f"{size:.1f} {unit}"
|
||||
size /= 1024.0
|
||||
return f"{size:.1f} TB"
|
||||
|
||||
@property
|
||||
def file_icon(self):
|
||||
"""Return Bootstrap icon class based on file type."""
|
||||
icon_map = {
|
||||
# Images
|
||||
'jpg': 'file-image',
|
||||
'jpeg': 'file-image',
|
||||
'png': 'file-image',
|
||||
'gif': 'file-image',
|
||||
'webp': 'file-image',
|
||||
'bmp': 'file-image',
|
||||
|
||||
# Documents
|
||||
'pdf': 'file-pdf',
|
||||
'doc': 'file-word',
|
||||
'docx': 'file-word',
|
||||
'txt': 'file-text',
|
||||
'rtf': 'file-text',
|
||||
|
||||
# Spreadsheets
|
||||
'xls': 'file-excel',
|
||||
'xlsx': 'file-excel',
|
||||
'csv': 'file-spreadsheet',
|
||||
|
||||
# Data files
|
||||
'xml': 'file-code',
|
||||
'json': 'file-code',
|
||||
|
||||
# 3D/CAD files
|
||||
'ldr': 'box-seam', # LDraw
|
||||
'mpd': 'box-seam', # LDraw
|
||||
'io': 'box-seam', # Stud.io
|
||||
'lxf': 'box-seam', # LEGO Digital Designer
|
||||
'lxfml': 'box-seam',
|
||||
|
||||
# Archives
|
||||
'zip': 'file-zip',
|
||||
'rar': 'file-zip',
|
||||
'7z': 'file-zip',
|
||||
'tar': 'file-zip',
|
||||
'gz': 'file-zip',
|
||||
|
||||
# Other
|
||||
'default': 'file-earmark'
|
||||
}
|
||||
|
||||
return icon_map.get(self.file_type.lower(), icon_map['default'])
|
||||
|
||||
@property
|
||||
def is_image(self):
|
||||
"""Check if file is an image."""
|
||||
image_types = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp']
|
||||
return self.file_type.lower() in image_types
|
||||
|
||||
@property
|
||||
def can_preview(self):
|
||||
"""Check if file can be previewed in browser."""
|
||||
preview_types = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'pdf', 'txt']
|
||||
return self.file_type.lower() in preview_types
|
||||
|
||||
def to_dict(self):
|
||||
"""Convert to dictionary for JSON responses."""
|
||||
return {
|
||||
'id': self.id,
|
||||
'set_id': self.set_id,
|
||||
'file_name': self.file_name,
|
||||
'original_filename': self.original_filename,
|
||||
'file_path': self.file_path.replace('\\', '/'),
|
||||
'file_type': self.file_type,
|
||||
'file_size': self.file_size,
|
||||
'file_size_formatted': self.file_size_formatted,
|
||||
'description': self.description,
|
||||
'category': self.category,
|
||||
'uploaded_at': self.uploaded_at.isoformat(),
|
||||
'is_image': self.is_image,
|
||||
'can_preview': self.can_preview,
|
||||
'file_icon': self.file_icon,
|
||||
'download_url': f'/extra-files/download/{self.id}'
|
||||
}
|
||||
Reference in New Issue
Block a user