diff --git a/muck/app.py b/muck/app.py new file mode 100644 index 0000000..f2134f6 --- /dev/null +++ b/muck/app.py @@ -0,0 +1,14 @@ +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker, scoped_session + +from muck.models.dbref import Base +from muck.init import bootstrap_world + +engine = create_engine("sqlite:///muck.db", echo=True) +SessionLocal = scoped_session(sessionmaker(bind=engine)) + +Base.metadata.create_all(engine) + +session = SessionLocal() + +bootstrap_world(session) diff --git a/muck/config.py b/muck/config.py new file mode 100644 index 0000000..e2815ee --- /dev/null +++ b/muck/config.py @@ -0,0 +1,3 @@ +class Config: + DB_URI = "sqlite:///muck.db" + DB_TRACK_MODIFICATIONS = False \ No newline at end of file diff --git a/muck/init.py b/muck/init.py new file mode 100644 index 0000000..03eca28 --- /dev/null +++ b/muck/init.py @@ -0,0 +1,39 @@ +from muck.models.room import Room +from muck.models.player import Player + +def bootstrap_world(session): + if session.query(Room).first() or session.query(Player).first(): + print("World already initialized.") + return + + print("Bootstrapping world...") + + room_zero = Room( + id=0, + name="Room Zero", + props={"_": {"de": "You are in Room Zero. It is very dark in here."}} + ) + + the_one = Player( + id=1, + name="One", + password="potrzebie", + props={"_": {"de": "You see The One."}} + ) + + the_one.location = room_zero + the_one.home = room_zero + + the_one.creator = the_one + the_one.owner = the_one + the_one.modifier = the_one + the_one.last_user = the_one + + room_zero.owner = the_one + room_zero.creator = the_one + room_zero.modifier = the_one + room_zero.last_user = the_one + + session.add_all([room_zero, the_one]) + session.commit() + print("World initialized.") diff --git a/muck/models/__init__.py b/muck/models/__init__.py new file mode 100644 index 0000000..1ee4e02 --- /dev/null +++ b/muck/models/__init__.py @@ -0,0 +1,5 @@ +from muck.models.dbref import Dbref +from muck.models.exit import Exit +from sqlalchemy.orm import relationship + +Dbref.exits = relationship("Exit", back_populates="source", foreign_keys=[Exit.location_id]) diff --git a/muck/models/dbref.py b/muck/models/dbref.py index 69d70db..5026161 100644 --- a/muck/models/dbref.py +++ b/muck/models/dbref.py @@ -1,5 +1,5 @@ from sqlalchemy import Column, Integer, String, ForeignKey, Boolean, DateTime, JSON, Enum as SQLEnum, func -from sqlalchemy.orm import relationship +from sqlalchemy.orm import relationship, foreign, remote from crudkit.core.base import CRUDMixin, Base from enum import Enum @@ -29,23 +29,22 @@ class Dbref(Base, CRUDMixin): last_used = Column(DateTime, nullable=False, default=func.now()) use_count = Column(Integer, nullable=False, default=0) - location_id = Column(Integer, ForeignKey("dbref.id"), nullable=False) - location = relationship("Dbref", remote_side=[CRUDMixin.id], foreign_keys=[location_id], back_populates="contents") + location_id = Column(Integer, ForeignKey("dbref.id"), nullable=True, default=0) + location = relationship("Dbref", foreign_keys=[location_id], back_populates="contents", primaryjoin=lambda: foreign(Dbref.location_id) == remote(Dbref.id), remote_side=lambda: Dbref.id) - contents = relationship("Dbref", backref="location", foreign_keys=location_id) - exits = relationship("Exit", backref="source", foreign_keys=location_id) + contents = relationship("Dbref", foreign_keys=[location_id], back_populates="location") - owner_id = Column(Integer, ForeignKey("dbref.id"), nullable=False) - owner = relationship("Player", remote_side=[CRUDMixin.id], foreign_keys=[owner_id]) + owner_id = Column(Integer, ForeignKey("dbref.id"), nullable=True) + owner = relationship("Player", remote_side=[CRUDMixin.id], foreign_keys=[owner_id], primaryjoin=lambda: Dbref.owner_id == remote(Dbref.id), post_update=True) - creator_id = Column(Integer, ForeignKey("dbref.id"), nullable=False) - creator = relationship("Player", remote_side=[CRUDMixin.id], foreign_keys=[creator_id]) + creator_id = Column(Integer, ForeignKey("dbref.id"), nullable=True) + creator = relationship("Player", remote_side=[CRUDMixin.id], foreign_keys=[creator_id], primaryjoin=lambda: Dbref.creator_id == remote(Dbref.id), post_update=True) - modifier_id = Column(Integer, ForeignKey("dbref.id"), nullable=False) - modifier = relationship("Player", remote_side=[CRUDMixin.id], foreign_keys=[modifier_id]) + modifier_id = Column(Integer, ForeignKey("dbref.id"), nullable=True) + modifier = relationship("Player", remote_side=[CRUDMixin.id], foreign_keys=[modifier_id], primaryjoin=lambda: Dbref.modifier_id == remote(Dbref.id), post_update=True) - last_user_id = Column(Integer, ForeignKey("dbref.id"), nullable=False) - last_user = relationship("Player", remote_side=[CRUDMixin.id], foreign_keys=[last_user_id]) + last_user_id = Column(Integer, ForeignKey("dbref.id"), nullable=True) + last_user = relationship("Player", remote_side=[CRUDMixin.id], foreign_keys=[last_user_id], primaryjoin=lambda: Dbref.last_user_id == remote(Dbref.id), post_update=True) __mapper_args__ = { "polymorphic_on": type, diff --git a/muck/models/exit.py b/muck/models/exit.py index a222bdc..5523100 100644 --- a/muck/models/exit.py +++ b/muck/models/exit.py @@ -1,5 +1,5 @@ from sqlalchemy import Column, Integer, ForeignKey -from sqlalchemy.orm import relationship +from sqlalchemy.orm import relationship, foreign, remote from crudkit.core.base import CRUDMixin @@ -11,8 +11,11 @@ class Exit(Dbref): id = Column(Integer, ForeignKey("dbref.id"), primary_key=True) destination_id = Column(Integer, ForeignKey("dbref.id"), nullable=True) - destination = relationship("Dbref", remote_side=[CRUDMixin.id], foreign_keys=[destination_id]) + destination = relationship("Dbref", remote_side=[CRUDMixin.id], foreign_keys=[destination_id], primaryjoin=lambda: foreign(Exit.destination_id) == remote(Dbref.id)) + + source = relationship("Dbref", back_populates="exits", foreign_keys=[Dbref.location_id], remote_side=[Dbref.id]) __mapper_args__ = { - "polymorphic_identity": ObjectType.EXIT + "polymorphic_identity": ObjectType.EXIT, + "inherit_condition": id == Dbref.id } diff --git a/muck/models/player.py b/muck/models/player.py index 99a3b22..6e1db75 100644 --- a/muck/models/player.py +++ b/muck/models/player.py @@ -1,5 +1,5 @@ from sqlalchemy import Column, Integer, Boolean, String, ForeignKey -from sqlalchemy.orm import relationship +from sqlalchemy.orm import relationship, foreign, remote from crudkit.core.base import CRUDMixin @@ -15,12 +15,13 @@ class Player(Dbref): block = Column(Integer, nullable=True) password = Column(String, nullable=False) - home_id = Column(Integer, ForeignKey("dbref.id"), nullable=False) - home = relationship("Dbref", remote_side=[CRUDMixin.id], foreign_keys=[home_id]) + home_id = Column(Integer, ForeignKey("dbref.id"), nullable=True) + home = relationship("Dbref", remote_side=[CRUDMixin.id], foreign_keys=[home_id], primaryjoin=lambda: foreign(Player.home_id) == remote(Dbref.id)) current_program_id = Column(Integer, ForeignKey("dbref.id"), nullable=True) - current_program = relationship("Dbref", remote_side=[CRUDMixin.id], foreign_keys=[current_program_id]) + current_program = relationship("Dbref", remote_side=[CRUDMixin.id], foreign_keys=[current_program_id], primaryjoin=lambda: foreign(Player.current_program_id) == remote(Dbref.id)) __mapper_args__ = { - "polymorphic_identity": ObjectType.PLAYER + "polymorphic_identity": ObjectType.PLAYER, + "inherit_condition": id == Dbref.id } diff --git a/muck/models/room.py b/muck/models/room.py index 49d5469..b0e5695 100644 --- a/muck/models/room.py +++ b/muck/models/room.py @@ -1,5 +1,5 @@ from sqlalchemy import Column, Integer, ForeignKey -from sqlalchemy.orm import relationship +from sqlalchemy.orm import relationship, foreign, remote from crudkit.core.base import CRUDMixin @@ -11,8 +11,9 @@ class Room(Dbref): id = Column(Integer, ForeignKey("dbref.id"), primary_key=True) dropto_id = Column(Integer, ForeignKey("dbref.id"), nullable=True) - dropto = relationship("Dbref", remote_side=[CRUDMixin.id], foreign_keys=[dropto_id]) + dropto = relationship("Dbref", remote_side=[CRUDMixin.id], foreign_keys=[dropto_id], primaryjoin=lambda: foreign(Room.dropto_id) == remote(Dbref.id)) __mapper_args__ = { - "polymorphic_identity": ObjectType.ROOM + "polymorphic_identity": ObjectType.ROOM, + "inherit_condition": id == Dbref.id }