<commit_before>#!/usr/bin/env python3
# -*- coding: utf8 -*-

import datetime
import hashlib

from sqlalchemy import Column, Integer, String, DateTime, Text, ForeignKey, Boolean
from sqlalchemy import func, or_, and_, desc
from sqlalchemy.orm import reconstructor, relationship, object_session

from smserver.smutils import smpacket
from smserver.models import schema, game, user, privilege

__all__ = ['Room']

class Room(schema.Base):
    __tablename__ = 'rooms'

    id             = Column(Integer, primary_key=True)
    name           = Column(String(255))
    motd           = Column(String(255))
    password       = Column(String(255))
    description    = Column(Text, default="")
    static         = Column(Boolean, default=False)
    ingame         = Column(Boolean, default=False)
    hidden         = Column(Boolean, default=False)

    status         = Column(Integer, default=0)
    type           = Column(Integer, default=1)
    max_users      = Column(Integer, default=255)

    users          = relationship("User", back_populates="room")
    games          = relationship("Game", back_populates="room")
    privileges     = relationship("Privilege", back_populates="room")
    bans           = relationship("Ban", back_populates="room")

    active_song_id = Column(Integer, ForeignKey('songs.id', ondelete="SET NULL"))
    active_song    = relationship("Song", back_populates="active_rooms")

    created_at     = Column(DateTime, default=datetime.datetime.now)
    updated_at     = Column(DateTime, onupdate=datetime.datetime.now)

    @reconstructor
    def _init_on_load(self):
        self._nb_players = None

    def __repr__(self):
        return "<Room #%s (name='%s')>" % (self.id, self.name)

    def to_packet(self):
        return smpacket.SMOPacketServerRoomUpdate(
            type=0,
            room_title=self.name,
            room_description=self.description,
            room_type=self.type
        )

    @property
    def last_game(self):
        return (object_session(self)
                .query(game.Game)
                .filter_by(room_id=self.id)
                .order_by(desc(game.Game.created_at))
                .first())

    @property
    def nb_players(self):
        if self._nb_players:
            return self._nb_players

        self._nb_players = (
            object_session(self)
            .query(func.count(user.User.id))
            .filter_by(online=True, room_id=self.id)
            .scalar())

        return self._nb_players

    @property
    def online_users(self):
        return (object_session(self)
                .query(user.User)
                .filter_by(online=True, room_id=self.id)
                .all())

    @property
    def room_info(self):
        packet = smpacket.SMOPacketServerRoomInfo(
            max_players=self.max_users
        )

        song = self.active_song
        if song:
            packet["song_title"] = song.title
            packet["song_subtitle"] = song.subtitle
            packet["song_artist"] = song.artist

        packet["players"] = [user.name for user in self.online_users]
        packet["num_players"] = len(packet["players"])

        return smpacket.SMPacketServerNSSMONL(packet=packet)

    @property
    def nsccuul(self):
        """ Return the NSCCUUL packets listing users in the room """

        users = self.online_users

        return smpacket.SMPacketServerNSCCUUL(
            max_players=self.max_users,
            nb_players=len(users),
            players=[{"status": u.enum_status.value, "name": u.name}
                     for u in users]
            )

    @staticmethod
    def list_to_smopacket(rooms):
        """ Take a list of rooms and return the formatted SMO packet"""

        packet = smpacket.SMOPacketServerRoomUpdate(
            type=1,
            nb_rooms=0,
            rooms=[],
            room_status=[],
            room_flags=[]
        )

        for room in rooms:
            packet["nb_rooms"] += 1
            packet["rooms"].append({
                "title": room.name,
                "description": room.description
            })
            packet['room_status'].append(room.status)
            packet['room_flags'].append(1 if room.password else 0)

        return smpacket.SMPacketServerNSSMONL(packet=packet)

    @classmethod
    def smo_list(cls, session, users=None, min_level=2):
        """
            Return the list of rooms already formatted in a SMO packet

            Send the list of room with:

            ```serv.send(models.Room.smo_list(session))```
        """

        return cls.list_to_smopacket(cls.available_rooms(session, users, min_level))

    @classmethod
    def available_rooms(cls, session, users=None, min_level=2):
        """
            Get the available rooms for the given user(s).

            If no users provided, return all the rooms
        """

        if not users:
            return session.query(cls)

        if not isinstance(users, list):
            users = [users]

        print(users)

        if max(users, key=lambda u: u.rank).rank >= min_level:
            return session.query(cls)

        query_privileges = []
        for usr in users:
            query_privileges.append(
                and_(
                    privilege.Privilege.user_id == usr.id,
                    privilege.Privilege.level >= min_level
                )<commit_msg>Remove debug print<commit_after>#!/usr/bin/env python3
# -*- coding: utf8 -*-

import datetime
import hashlib

from sqlalchemy import Column, Integer, String, DateTime, Text, ForeignKey, Boolean
from sqlalchemy import func, or_, and_, desc
from sqlalchemy.orm import reconstructor, relationship, object_session

from smserver.smutils import smpacket
from smserver.models import schema, game, user, privilege

__all__ = ['Room']

class Room(schema.Base):
    __tablename__ = 'rooms'

    id             = Column(Integer, primary_key=True)
    name           = Column(String(255))
    motd           = Column(String(255))
    password       = Column(String(255))
    description    = Column(Text, default="")
    static         = Column(Boolean, default=False)
    ingame         = Column(Boolean, default=False)
    hidden         = Column(Boolean, default=False)

    status         = Column(Integer, default=0)
    type           = Column(Integer, default=1)
    max_users      = Column(Integer, default=255)

    users          = relationship("User", back_populates="room")
    games          = relationship("Game", back_populates="room")
    privileges     = relationship("Privilege", back_populates="room")
    bans           = relationship("Ban", back_populates="room")

    active_song_id = Column(Integer, ForeignKey('songs.id', ondelete="SET NULL"))
    active_song    = relationship("Song", back_populates="active_rooms")

    created_at     = Column(DateTime, default=datetime.datetime.now)
    updated_at     = Column(DateTime, onupdate=datetime.datetime.now)

    @reconstructor
    def _init_on_load(self):
        self._nb_players = None

    def __repr__(self):
        return "<Room #%s (name='%s')>" % (self.id, self.name)

    def to_packet(self):
        return smpacket.SMOPacketServerRoomUpdate(
            type=0,
            room_title=self.name,
            room_description=self.description,
            room_type=self.type
        )

    @property
    def last_game(self):
        return (object_session(self)
                .query(game.Game)
                .filter_by(room_id=self.id)
                .order_by(desc(game.Game.created_at))
                .first())

    @property
    def nb_players(self):
        if self._nb_players:
            return self._nb_players

        self._nb_players = (
            object_session(self)
            .query(func.count(user.User.id))
            .filter_by(online=True, room_id=self.id)
            .scalar())

        return self._nb_players

    @property
    def online_users(self):
        return (object_session(self)
                .query(user.User)
                .filter_by(online=True, room_id=self.id)
                .all())

    @property
    def room_info(self):
        packet = smpacket.SMOPacketServerRoomInfo(
            max_players=self.max_users
        )

        song = self.active_song
        if song:
            packet["song_title"] = song.title
            packet["song_subtitle"] = song.subtitle
            packet["song_artist"] = song.artist

        packet["players"] = [user.name for user in self.online_users]
        packet["num_players"] = len(packet["players"])

        return smpacket.SMPacketServerNSSMONL(packet=packet)

    @property
    def nsccuul(self):
        """ Return the NSCCUUL packets listing users in the room """

        users = self.online_users

        return smpacket.SMPacketServerNSCCUUL(
            max_players=self.max_users,
            nb_players=len(users),
            players=[{"status": u.enum_status.value, "name": u.name}
                     for u in users]
            )

    @staticmethod
    def list_to_smopacket(rooms):
        """ Take a list of rooms and return the formatted SMO packet"""

        packet = smpacket.SMOPacketServerRoomUpdate(
            type=1,
            nb_rooms=0,
            rooms=[],
            room_status=[],
            room_flags=[]
        )

        for room in rooms:
            packet["nb_rooms"] += 1
            packet["rooms"].append({
                "title": room.name,
                "description": room.description
            })
            packet['room_status'].append(room.status)
            packet['room_flags'].append(1 if room.password else 0)

        return smpacket.SMPacketServerNSSMONL(packet=packet)

    @classmethod
    def smo_list(cls, session, users=None, min_level=2):
        """
            Return the list of rooms already formatted in a SMO packet

            Send the list of room with:

            ```serv.send(models.Room.smo_list(session))```
        """

        return cls.list_to_smopacket(cls.available_rooms(session, users, min_level))

    @classmethod
    def available_rooms(cls, session, users=None, min_level=2):
        """
            Get the available rooms for the given user(s).

            If no users provided, return all the rooms
        """

        if not users:
            return session.query(cls)

        if not isinstance(users, list):
            users = [users]

        if max(users, key=lambda u: u.rank).rank >= min_level:
            return session.query(cls)

        query_privileges = []
        for usr in users:
            query_privileges.append(
                and_(
                    privilege.Privilege.user_id == usr.id,
                    privilege.Privilege.level >= min_level
                )
{'fraction_non_alphanumeric': 0.10457880560973344, 'fraction_numerical': 0.004458066313736417, 'mean_word_length': 2.075692659240217, 'pattern_counts': {'":': 8, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '203074', 'n_tokens_mistral': 3172, 'n_tokens_neox': 3031, 'n_words': 663}