library.py 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. """Library models for file manager functionality."""
  2. from datetime import datetime
  3. from sqlalchemy import JSON, Boolean, DateTime, ForeignKey, Integer, String, Text, func
  4. from sqlalchemy.orm import Mapped, mapped_column, relationship
  5. from backend.app.core.database import Base
  6. class LibraryFolder(Base):
  7. """Folder for organizing library files."""
  8. __tablename__ = "library_folders"
  9. id: Mapped[int] = mapped_column(primary_key=True)
  10. name: Mapped[str] = mapped_column(String(255))
  11. parent_id: Mapped[int | None] = mapped_column(ForeignKey("library_folders.id", ondelete="CASCADE"), nullable=True)
  12. # External folder flags (for folders that point to external paths)
  13. is_external: Mapped[bool] = mapped_column(Boolean, default=False)
  14. external_readonly: Mapped[bool] = mapped_column(Boolean, default=False)
  15. external_show_hidden: Mapped[bool] = mapped_column(Boolean, default=False)
  16. external_path: Mapped[str | None] = mapped_column(String(500), nullable=True)
  17. # Link to project or archive
  18. project_id: Mapped[int | None] = mapped_column(ForeignKey("projects.id", ondelete="SET NULL"), nullable=True)
  19. archive_id: Mapped[int | None] = mapped_column(ForeignKey("print_archives.id", ondelete="SET NULL"), nullable=True)
  20. # Timestamps
  21. created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
  22. updated_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), onupdate=func.now())
  23. # Relationships
  24. parent: Mapped["LibraryFolder | None"] = relationship(
  25. "LibraryFolder",
  26. back_populates="children",
  27. remote_side="LibraryFolder.id",
  28. foreign_keys="LibraryFolder.parent_id",
  29. )
  30. children: Mapped[list["LibraryFolder"]] = relationship(
  31. "LibraryFolder",
  32. back_populates="parent",
  33. foreign_keys="LibraryFolder.parent_id",
  34. cascade="all, delete-orphan",
  35. )
  36. files: Mapped[list["LibraryFile"]] = relationship(
  37. back_populates="folder",
  38. cascade="all, delete-orphan",
  39. )
  40. project: Mapped["Project | None"] = relationship()
  41. archive: Mapped["PrintArchive | None"] = relationship()
  42. class LibraryFile(Base):
  43. """File stored in the library."""
  44. __tablename__ = "library_files"
  45. id: Mapped[int] = mapped_column(primary_key=True)
  46. folder_id: Mapped[int | None] = mapped_column(ForeignKey("library_folders.id", ondelete="CASCADE"), nullable=True)
  47. project_id: Mapped[int | None] = mapped_column(ForeignKey("projects.id", ondelete="SET NULL"), nullable=True)
  48. # External file flag
  49. is_external: Mapped[bool] = mapped_column(Boolean, default=False)
  50. # File info
  51. filename: Mapped[str] = mapped_column(String(255)) # Original filename
  52. file_path: Mapped[str] = mapped_column(String(500)) # Storage path
  53. file_type: Mapped[str] = mapped_column(String(10)) # "3mf" or "gcode"
  54. file_size: Mapped[int] = mapped_column(Integer)
  55. file_hash: Mapped[str | None] = mapped_column(String(64)) # SHA256 for duplicate detection
  56. thumbnail_path: Mapped[str | None] = mapped_column(String(500))
  57. # Extracted metadata (from 3MF parser)
  58. file_metadata: Mapped[dict | None] = mapped_column(JSON)
  59. # Usage tracking
  60. print_count: Mapped[int] = mapped_column(Integer, default=0)
  61. last_printed_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
  62. # User notes
  63. notes: Mapped[str | None] = mapped_column(Text, nullable=True)
  64. # Timestamps
  65. created_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now())
  66. updated_at: Mapped[datetime] = mapped_column(DateTime, server_default=func.now(), onupdate=func.now())
  67. # Relationships
  68. folder: Mapped["LibraryFolder | None"] = relationship(back_populates="files")
  69. project: Mapped["Project | None"] = relationship()
  70. from backend.app.models.archive import PrintArchive # noqa: E402, F811
  71. from backend.app.models.project import Project # noqa: E402, F811