Esempio n. 1
0
class PlayerTreeDAO(IPlayerTreeDAO):
    """
    DAO for tree widget
    """
    TABLE_NAME = 'player_tree_structure'
    DATABASE_DRIVER = "file::memory:?cache=shared"

    def __init__(self):
        self.database = Database(self.DATABASE_DRIVER)

    def get_root_nodes(self, target_type: ObjectType) -> list:
        """
        Get all nodes with parent null
        :param target_type: Type of object
        :return: list of root nodes
        """
        data = self.database.select(self.TABLE_NAME, {
            'parent_id': None,
            'parent_type': target_type.value
        })

        return map_objects(data)

    def get_nodes_search(self, targetType: ObjectType, text: str):
        """
        Get nodes witch name contain searched text
        :param targetType: Type of object in node
        :param text: searching text
        :return: list of nodes with text included
        """
        data = self.database.select(self.TABLE_NAME, {
            'parent_type': targetType.value,
            'name': ('like', '%' + text + '%')
        })
        return map_objects(data)

    def get_node(self, id: int) -> Node:
        """
        Get node by id
        :param id: id of node
        :return: node object if exist, None otherwise
        """
        data = self.database.select(self.TABLE_NAME, {'ID': id})
        return map_objects(data)[0] if len(data) > 0 else None

    def get_children_objects(self, parentNodeId: int,
                             contextType: ObjectType) -> list:
        """
        Recursively find all child object of give type, only first level object (folders will be skipped and searching deep
        :param parentNodeId parent node, where you finding
        :param contextType object type of tree
        :return: list of objects in tree
        """

        nodes = self.get_children_nodes(contextType, parentNodeId)

        objects = []
        for node in nodes:
            if isinstance(node, Folder):
                objects += self.get_children_nodes(contextType, node.id)
            else:
                objects.append(node)

        return objects

    def __get_children_objects(self,
                               targetType,
                               nodeId: int,
                               parentType: ObjectType,
                               objects: list = None,
                               direct: bool = False):
        """
        Private function, return all children object of target node
        :param targetType: Object type
        :param nodeId: id of target node
        :param parentType: Context type
        :param objects: list of object for recursion
        :param direct: if true, only first level child will be add to object list 
        :return: list of children
        """
        if objects is None:
            objects = []

        children = self.get_children_nodes(parentType, nodeId)

        for child in children:
            if direct and isinstance(
                    child,
                    NodeObject) and child.object.object_type is not targetType:
                continue

            objects = self.__get_children_objects(targetType,
                                                  child.id,
                                                  parentType,
                                                  objects,
                                                  direct=direct)
            if isinstance(
                    child,
                    NodeObject) and child.object.object_type is targetType:
                objects.append(child.object)

        return objects

    def get_children_nodes(self, contextType: ObjectType,
                           parent_id: int) -> list:
        """
        Get all child of parent id
        :param target_type: target type
        :param parent_id: parent id
        :return: list of nodes with parent id, or empty list
        """
        data = self.database.select(self.TABLE_NAME, {
            'parent_id': parent_id,
            'parent_type': contextType.value
        })

        return map_objects(data)

    def update_node(self, node: Node):
        """
        Update node data
        :param node: node
        """
        if isinstance(node, Folder):
            values = {'parent_id': node.parent_id, 'name': node.name}
        else:
            values = {
                'target_id': node.object.id,
                'parent_id': node.parent_id,
                'name': node.name
            }
        self.database.update(self.TABLE_NAME, node.id, values)

    def insert_node(self, node: Node, object_type: ObjectType) -> int:
        """
        Create new node in database
        :param node: node object
        :return: id of created node
        """

        if isinstance(node, Folder):
            values = {
                'parent_type': object_type.value,
                'parent_id': node.parent_id,
                'type': NodeType.FOLDER.value,
                'name': node.name
            }
        else:
            values = {
                'target_type': node.object.object_type.value,
                'parent_type': object_type.value,
                'target_id': node.object.id,
                'parent_id': node.parent_id,
                'type': NodeType.OBJECT.value,
                'name': node.name
            }
        return self.database.insert(self.TABLE_NAME, values)

    def delete_node(self, id: int):
        """
        Delete node from database
        :param id: id of node
        """
        self.database.delete(self.TABLE_NAME, id)

    def get_node_by_object(self, object: object):
        """
        Return node based on object
        :param object: object that you finding
        :return: ObjectNode with object 
        """
        data = self.database.select(self.TABLE_NAME, {
            'target_id': object.id,
            'parent_type': object.object_type.value
        })

        return self.get_node(data[0]['id'])
Esempio n. 2
0
class MapItemDAO(IMapItemDAO):
    DATABASE_TABLE = 'Map_item'
    DATABASE_DRIVER = "file::memory:?cache=shared"
    TYPE = ObjectType.MAP_ITEM


    def __init__(self):
        self.database = Database(self.DATABASE_DRIVER)


    def create(self, mapItem: MapItem) -> int:
        """
        Create new map item        
        :param mapItem: Map object        
        :return: id of created mapItem
        """
        X = mapItem.coord.x()
        Y = mapItem.coord.y()

        values = {
            'name'       : mapItem.name,
            'description': mapItem.description,
            'number'     : mapItem.number,
            'scale'      : mapItem.scale,
            'positionX'  : X,
            'positionY'  : Y,
            'map_id'     : mapItem.mapId,
            'itemType'   : mapItem.itemType.value
        }
        id = self.database.insert(self.DATABASE_TABLE, values)

        return id


    def update(self, mapItem: MapItem):
        """
        Update map item in database
        :param mapItem: mapItem object with new data
        """
        X = mapItem.coord.x()
        Y = mapItem.coord.y()

        values = {
            'name'       : mapItem.name,
            'description': mapItem.description,
            'number'     : mapItem.number,
            'scale'      : mapItem.scale,
            'positionX'  : X,
            'positionY'  : Y,
        }

        self.database.update(self.DATABASE_TABLE, mapItem.id, values)


    def delete(self, mapitem_id: int):
        """
        Delete Map item from database and all his translates
        :param mapitem_id: id of Map item
        """
        self.database.delete(self.DATABASE_TABLE, mapitem_id)


    def get(self, mapitem_id: int) -> MapItem:
        """
        Get map item from database
        :param mapitem_id: id of map item        
        :return: Map item object
        """

        data = dict(self.database.select(self.DATABASE_TABLE, {'ID': mapitem_id})[0])

        coord = QPointF(data.get('positionX', 0), data.get('positionY', 0))

        itemType = MapItemType(data.get('itemType'))

        mapitem = MapItem(mapitem_id, data.get('name', ''), data.get('description', ''), coord,
                          data.get('scale', 0), data.get('number', 0), None, data.get('map_id'), itemType)

        return mapitem


    def get_all(self, lang=None) -> list:
        """
        Get list of map items for selected lang
        :param lang: lang of map items
        :return: list of map items
        """
        if lang is None:
            lang = SettingsDAO().get_value('language', str)
        lines = self.database.select_all(self.DATABASE_TABLE)
        mapItems = []
        for line in lines:
            item = self.get(line['ID'], lang)
            mapItems.append(item)
        return mapItems
Esempio n. 3
0
class PartyCharacterDAO(DAO, IPartyCharacterDAO):
    DATABASE_TABLE = 'PartyCharacter'
    TYPE = ObjectType.CHARACTER

    def __init__(self):
        self.database = Database(self.DATABASE_DRIVER)

    def create(self,
               character: PartyCharacter,
               nodeParentId: int = None,
               contextType: ObjectType = None) -> int:
        """
        Create new PartyCharacter, if character given, linked with character and create character
                                   if character is not given, only party character created and liked with scenario
        :param character: PartyCharacter object
        :param nodeParentId: id of parent node in tree
        :param contextType: Object type of tree, where item is located
        :return: id of created character
        """
        if not contextType:
            contextType = self.TYPE

        if character.character:
            if type(character.character) is dict:
                character_id = CharacterDAO().create(
                    character.character.popitem()[1], nodeParentId,
                    contextType)  # TODO: default lang
            else:
                character_id = CharacterDAO().create(
                    character.character, nodeParentId,
                    contextType)  # TODO: default lang
        else:
            character_id = None

        if nodeParentId:
            scenario = PlayerTreeDAO().get_node(nodeParentId).object
        else:
            scenario = None

        intValues = {
            'deviceName': character.deviceName,
            'MACAddress': character.MACAddress,
            'character_id': character_id,
            'scenario_id': scenario.id if scenario else None,
            'name': character.name,
        }

        id = self.database.insert(self.DATABASE_TABLE, intValues)
        character.id = id

        for message in character.messages:
            message.partyCharacterId = id
            MessageDAO().create(message)

        return id

    def update(self, character: PartyCharacter):
        """
        Update party PartyCharacter in database, update only party character, not Character
        :param character: PartyCharacter object with new data
        """
        intValues = {
            'deviceName': character.deviceName,
            'MACAddress': character.MACAddress,
            'name': character.name
        }

        self.database.update(self.DATABASE_TABLE, character.id, intValues)

    def delete(self, character_id: int):
        """
        Delete party character from database and all his translates
        :param character_id: id of party character
        """
        self.database.delete(self.DATABASE_TABLE, character_id)

    def get(self,
            character_id: int,
            lang: str = None,
            nodeId: int = None,
            contextType: ObjectType = None) -> PartyCharacter:
        """
        Get Party Character by character id, object transable attributes depends on lang
        If nodeId and contextType is specified, whole object is returned (with all sub objects)
        If not specified, only basic attributes are set.        
        :param character_id: id of Party Character
        :param lang: lang of object
        :param nodeId: id of node in tree, where object is located
        :param contextType: object type of tree, where is node
        :return: Party Character object
        """
        if lang is None:
            lang = SettingsDAO().get_value('language', str)

        select = self.database.select(self.DATABASE_TABLE,
                                      {'character_id': character_id})

        if not select:
            return None

        data = dict(select[0])

        character = PartyCharacter(data.get('ID'), lang, data['name'], None,
                                   data.get('deviceName', ''),
                                   data.get('MACAddress'))

        messages = MessageDAO().get_by_party_character(character.id)

        character.messages = messages

        # character.character = CharacterDAO().get(data.get('character_id'))

        return character

    def get_by_id(self,
                  partyCharacterId: int,
                  lang: str = None) -> PartyCharacter:
        """
        Get party character by id, without character
        :param partyCharacterId: party character ID
        :param lang: lang of object
        :return: Party character object
        """
        data = dict(
            self.database.select(self.DATABASE_TABLE,
                                 {'ID': partyCharacterId})[0])

        character = PartyCharacter(data.get('ID'), lang, data['name'], None,
                                   data.get('deviceName', ''),
                                   data.get('MACAddress'))

        return character

    def get_all(self, lang=None) -> list:
        """
        Get list of all Party Characters from database, only one lang
        :param lang: lang code
        :return: list of Party Characters
        """
        if lang is None:
            lang = SettingsDAO().get_value('language', str)
        lines = self.database.select_all(self.DATABASE_TABLE)
        characters = []
        for line in lines:
            character = self.get(line['ID'], lang)
            characters.append(character)
        return characters
Esempio n. 4
0
class MapDAO(DAO, IMapDAO):
    DATABASE_TABLE = 'Map'
    TYPE = ObjectType.MAP

    def __init__(self):
        self.database = Database(self.DATABASE_DRIVER)
        self.treeDAO = PlayerTreeDAO()

    def create(self,
               map: Map,
               nodeParentId: int = None,
               contextType: ObjectType = None) -> int:
        """
        Create new map and create empty map image, because of exporting        
        :param map: Map object
        :param nodeParentId: id of parent node in tree
        :param contextType: Object type of tree, where item is located
        :return: id of created map
        """
        if contextType is None:
            contextType = self.TYPE

        values = {
            'name': map.name if map.name else '',
            'description': map.description if map.description else '',
            'map_file': map.mapFile,
        }

        id = self.database.insert(self.DATABASE_TABLE, values)
        map.id = id

        node = NodeObject(None, map.name, nodeParentId, map)
        nodeId = self.treeDAO.insert_node(node, contextType)

        for mapItem in map.mapItems:
            mapItem.mapId = id
            MapItemDAO().create(mapItem)

        self.create_map_image(map)
        return id

    def update(self, map: Map):
        """
        Update map in database
        :param map: Location object with new data
        """
        values = {
            'name': map.name,
            'description': map.description,
            'map_file': map.mapFile,
        }

        self.database.set_many(True)
        for mapItem in map.mapItems:
            MapItemDAO().update(mapItem)

        self.database.insert_many_execute()
        self.database.set_many(False)

        self.database.update(self.DATABASE_TABLE, map.id, values)

    def delete(self, map_id: int):
        """
        Delete Map from database and from translate and delete all maps linked with map
        :param map_id: id of Map
        """
        map = self.get(map_id)
        self.database.delete(self.DATABASE_TABLE, map_id)
        os.remove(map.mapFile)
        os.remove('resources/maps/exportedMap-1.png')

    def get(self,
            map_id: int,
            lang: str = None,
            nodeId: int = None,
            contextType: ObjectType = None) -> Map:
        """
        Get Map , object transable attributes depends on lang
        If nodeId and contextType is specified, whole object is returned (with all sub objects)
        If not specified, only basic attributes are set.        
        :param map_id: id of Map
        :param lang: lang of object
        :param nodeId: id of node in tree, where object is located
        :param contextType: object type of tree, where is node
        :return: Map object
        """

        data = self.database.select(self.DATABASE_TABLE, {'ID': map_id})

        if not data:
            return None
        else:
            data = dict(data[0])

        map = Map(map_id, None, data.get('name', ' '),
                  data.get('description', ' '), data.get('map_file', None))

        sql = self.database.select('Map_item', {'map_id': map.id})

        map.XMLMap = 'map-{}.png'.format(map_id)
        mapItems = []
        for line in sql:
            mapItem = MapItemDAO().get(line['ID'])
            mapItems.append(mapItem)
        map.mapItems = mapItems

        return map

    def get_all(self, lang=None) -> list:
        """
        Get list of maps for selected lang
        :param lang: lang of maps
        :return: list of maps
        """
        if lang is None:
            lang = SettingsDAO().get_value('language', str)
        lines = self.database.select_all(self.DATABASE_TABLE)
        maps = []
        for line in lines:
            item = self.get(line['ID'], lang)
            maps.append(item)
        return maps

    def create_map_image(self, map: Map) -> None:
        """
        Create empty image for map, important because of exporting
        :param map: map object         
        """
        from PyQt5.QtWidgets import QGraphicsView
        from PyQt5.QtWidgets import QGraphicsScene
        from PyQt5.QtGui import QPainter, QPixmap
        from PyQt5.QtGui import QImage
        from presentation.widgets.MapWidget import MapItemDraw

        grview = QGraphicsView()
        grview.setRenderHints(grview.renderHints() | QPainter.Antialiasing
                              | QPainter.SmoothPixmapTransform)

        scene = QGraphicsScene()
        grview.setScene(scene)
        if not map.mapFile:
            mapFile = 'resources/icons/no_map.png'
        else:
            mapFile = map.mapFile
        pixMap = QPixmap(mapFile)
        sceneMap = scene.addPixmap(pixMap)

        for num, mapItem in enumerate(map.mapItems):
            mapItem.number = num + 1
            item = MapItemDraw(mapItem, None)
            scene.addItem(item)
            # self.map.addMapItemDraws(item)

        scene.setSceneRect(scene.itemsBoundingRect())
        img = QImage(scene.sceneRect().size().toSize(), QImage.Format_ARGB32)

        painter = QPainter(img)
        scene.render(painter)

        name = 'resources/maps/exportedMap-{}.png'.format(map.id)
        img.save(name)

        del painter
Esempio n. 5
0
class MessageDAO(DAO, IMessageDAO):
    DATABASE_TABLE = 'Message'
    TYPE = ObjectType.MESSAGE


    def __init__(self):
        self.database = Database(self.DATABASE_DRIVER)


    def create(self, message: Message) -> int:
        """
        Create new message in database
        :param message: Message object
        :return: id of autoincrement
        """
        curDate = datetime.strptime(message.date, '%d/%m/%Y %H:%M:%S') if message.date else None

        if type(message.isMine) is str:
            isMine = True if message.isMine == 'true' else False
        else:
            isMine = message.isMine

        intValues = {
            'text'            : message.text,
            'date'            : curDate.toordinal() if curDate else None,
            'isMine'          : int(isMine),
            'characterId'     : message.characterId,
            'partyCharacterId': message.partyCharacterId
        }

        id = self.database.insert(self.DATABASE_TABLE, intValues)
        message.id = id

        return id


    def update(self, message: Message):
        """
        Update message in database
        :param message: Message object with new data
        """
        if type(message.isMine) is str:
            isMine = True if message.isMine == 'true' else False
        else:
            isMine = message.isMine

        intValues = {
            'text'  : message.text,
            'date'  : message.date.toordinal(),
            'isMine': int(isMine)
        }

        self.database.update(self.DATABASE_TABLE, message.id, intValues)


    def delete(self, message_id: int):
        """
        Delete Message from database and all his translates
        :param message_id: id of Message
        """
        self.database.delete(self.DATABASE_TABLE, message_id)


    def get(self, message_id: int, lang: str = None) -> Message:
        """
        Get Message from database
        :param message_id: id of Message
        :param lang: lang of spell
        :return: Message object
        """
        if lang is None:
            lang = SettingsDAO().get_value('language', str)

        data = dict(self.database.select(self.DATABASE_TABLE, {'ID': message_id})[0])

        curDate = datetime.fromordinal(data.get('date')) if data.get('date') else None

        message = Message(message_id, data['text'], curDate, bool(data['isMine']), data.get('partyCharacterId'),
                          data.get('characterId'))

        return message


    def get_by_party_character(self, partyCharacterId: int) -> list:
        """
        Get all messages for one party character
        :param partyCharacterId: id of party character
        :return: list of Messages
        """
        select = self.database.select(self.DATABASE_TABLE, {'partyCharacterId': partyCharacterId})

        messages = []
        for one in select:
            data = dict(one)
            curDate = date.fromordinal(data.get('date')) if data.get('date') else None
            message = Message(data.get('id'), data.get('text', ''), curDate, bool(data['isMine']), data.get('partyCharacterId'),
                              None)

            messages.append(message)

        return messages


    def get_all(self, lang=None) -> list:
        """
        Get list of all messages from database, only one lang
        :param lang: lang code
        :return: list of messages
        """
        if lang is None:
            lang = SettingsDAO().get_value('language', str)
        lines = self.database.select_all(self.DATABASE_TABLE)
        characters = []
        for line in lines:
            character = self.get(line['ID'], lang)
            characters.append(character)
        return characters