Пример #1
0
class TestGui4(MyGui):
    def initVars(self):
        self.collection = SimpleCollection(filename="simple_test.db")
        it = self.collection.get()
        for i in it:
            print(">>", i)

    def setupUi(self):
        super().setupUi()

        self.lis = TestList(collection=self.collection)
        self.lis.widget.setParent(self.w)
        self.lay.addWidget(self.lis.widget)

        self.formset = TestEditFormSet(collection=self.collection)
        self.formset.widget.setParent(self.w)
        self.lay.addWidget(self.formset.widget)

        self.lis.widget.currentItemChanged.connect(
            self.formset.chooseForm_slot
        )  # inform formset about the item in question
        self.formset.signals.new_record.connect(
            self.lis.update_slot
        )  # inform list that a new entry has been added

    def closeEvent(self, e):
        print("close event!")
        self.collection.close()
        e.accept()
Пример #2
0
class TestGui2(MyGui):
    def initVars(self):
        self.collection = SimpleCollection(filename="simple_test.db")
        it = self.collection.get()
        for i in it:
            print(">>", i)

    def setupUi(self):
        super().setupUi()
        self.lis = TestList(collection=self.collection)
        self.lis.widget.setParent(self.w)
        self.lay.addWidget(self.lis.widget)

    def closeEvent(self, e):
        print("close event!")
        self.collection.close()
        e.accept()
Пример #3
0
    def define(self):
        """Define column patterns and collections
        """
        self.collections = []

        self.camera_collection = \
            SimpleCollection(filename=os.path.join(self.directory, "devices.dat"),
                             row_classes=[
                DataModel.EmptyRow,
                DataModel.RTSPCameraRow,
                DataModel.USBCameraRow
            ]
            )
        self.collections.append(self.camera_collection)

        self.config_collection = \
            SimpleCollection(filename=os.path.join(self.directory, "config.dat"),
                             row_classes=[  # we could dump here all kinds of info related to different kind of configuration forms
                DataModel.MemoryConfigRow
            ]
            )
        self.collections.append(self.config_collection)
Пример #4
0
    def define(self):
        """Define column patterns and collections
        """
        self.collections = []

        self.camera_collection = \
            SimpleCollection(filename=os.path.join(self.directory, "devices.dat"),
                             row_classes=[
                    EmptyRow,
                    RTSPCameraRow,
                    USBCameraRow,
                    SDPFileRow
                ]
            )
        self.collections.append(self.camera_collection)

        self.config_collection = \
            SimpleCollection(filename=os.path.join(self.directory, "config.dat"),
                row_classes=[  # we could dump here all kinds of info related to different kind of configuration forms
                    MemoryConfigRow
                ]
            )
        self.collections.append(self.config_collection)

        self.valkkafs_collection = \
            SimpleCollection(filename=os.path.join(self.directory, "valkkafs.dat"),
                row_classes=[
                    ValkkaFSConfigRow
                ]
            )
        self.collections.append(self.valkkafs_collection)
        """
        self.layout_collection = \
            SimpleCollection(filename=os.path.join(self.directory, "layout.dat"),
                row_classes=[
                    VideoContainerNxMRow,
                    PlayVideoContainerNxMRow,
                    CameraListWindowRow,
                    MainWindowRow
                ]
            )
        """
        self.layout_collection = \
            SimpleCollection(filename=os.path.join(self.directory, "layout.dat"),
                row_classes=[
                    LayoutContainerRow
                ]
            )

        self.collections.append(self.layout_collection)
Пример #5
0
    def initVars(self):
        # users
        self.collection1 = SimpleCollection(filename="simple_test6a.db")
        self.collection1.clear()

        # cars
        self.collection2 = SimpleCollection(filename="simple_test6b.db")
        self.collection2.clear()

        # permissions
        self.collection3 = SimpleCollection(filename="simple_test6c.db")
        self.collection3.clear()
Пример #6
0
 def initVars(self):
     self.collection = SimpleCollection(filename="simple_test.db")
     it = self.collection.get()
     for i in it:
         print(">>", i)
Пример #7
0
class TestGui6(MyGui):
    """Left: list of records (users).  Right: list of cards.  Rightmost: user rights.
  """

    # LineEditColumn(field_name="firstname",label_name="First Name", ..)
    # ComboBoxColum(collection=.., key_column_name=..,field_name=..,label_name="Car model")

    def initVars(self):
        # users
        self.collection1 = SimpleCollection(filename="simple_test6a.db")
        self.collection1.clear()

        # cars
        self.collection2 = SimpleCollection(filename="simple_test6b.db")
        self.collection2.clear()

        # permissions
        self.collection3 = SimpleCollection(filename="simple_test6c.db")
        self.collection3.clear()

    def setupUi(self):
        super().setupUi()

        # we need self.side_collection, hence the definitions here
        class Row1(Row):
            columns = [
                ColumnSpec(LineEditColumn,
                           key_name="name",
                           label_name="First Name"),
                ColumnSpec(LineEditColumn,
                           key_name="surname",
                           label_name="Last Name")
            ]

        class Row2(Row):
            columns = [
                ColumnSpec(LineEditColumn,
                           key_name="brand",
                           label_name="Brand"),
                ColumnSpec(LineEditColumn, key_name="year", label_name="Year")
            ]

        class LinkRow(Row):
            columns = [
                ColumnSpec(ForeignKeyColumn, key_name="user_key"),
                ColumnSpec(ForeignKeyColumn, key_name="car_key"),
                ColumnSpec(CheckBoxColumn,
                           key_name="drive",
                           label_name="Can drive"),
                ColumnSpec(CheckBoxColumn,
                           key_name="sell",
                           label_name="Can sell")
            ]

        class TestList1(List):
            def makeLabel(self, entry):
                return entry["name"] + " " + entry["surname"]

        class TestList2(List):
            def makeLabel(self, entry):
                return entry["brand"]

        class TestFormSet1(FormSet):
            row_classes = [Row1]

        class TestFormSet2(FormSet):
            row_classes = [Row2]

        class TestFormSet3(PermissionFormSet):
            row_classes = [LinkRow]

        self.collection1.new(Row1, {"name": "Antti", "surname": "Mykkanen"})
        self.collection1.new(Row1, {"name": "Jonne", "surname": "Paananen"})
        self.collection1.new(Row1, {"name": "Juho", "surname": "Kokkonen"})
        self.collection1.new(Row1, {"name": "Janne", "surname": "Suhonen"})

        self.collection2.new(Row2, {"brand": "Ford", "year": 2000})
        self.collection2.new(Row2, {"brand": "Audi", "year": 1996})
        self.collection2.new(Row2, {"brand": "Seat", "year": 2004})
        self.collection2.new(Row2, {"brand": "Yugo", "year": 1985})
        self.collection2.new(Row2, {"brand": "BMW", "year": 2016})

        self.lis1 = TestList1(collection=self.collection1)
        self.lis1.widget.setParent(self.w)
        self.lay.addWidget(self.lis1.widget)

        self.formset1 = TestFormSet1(collection=self.collection1)
        self.formset1.widget.setParent(self.w)
        self.lay.addWidget(self.formset1.widget)

        self.lis2 = TestList2(collection=self.collection2)
        self.lis2.widget.setParent(self.w)
        self.lay.addWidget(self.lis2.widget)

        self.formset2 = TestFormSet2(collection=self.collection2)
        self.formset2.widget.setParent(self.w)
        self.lay.addWidget(self.formset2.widget)

        self.formset3 = TestFormSet3(collection=self.collection3,
                                     key1_name="user_key",
                                     key2_name="car_key")
        self.formset3.widget.setParent(self.w)
        self.lay.addWidget(self.formset3.widget)

        self.lis1.widget.currentItemChanged.connect(
            self.formset1.chooseForm_slot
        )  # inform formset about the item in question
        self.lis2.widget.currentItemChanged.connect(
            self.formset2.chooseForm_slot
        )  # inform formset about the item in question

        # connect the user/car pair to the permission form
        self.lis1.widget.currentItemChanged.connect(
            self.formset3.pingCol1_slot
        )  # inform formset about the item in question
        self.lis2.widget.currentItemChanged.connect(
            self.formset3.pingCol2_slot
        )  # inform formset about the item in question

        # self.formset1.signals.new_record.        connect(self.lis1.update_slot)         # inform list that a new entry has been added

    def closeEvent(self, e):
        print("close event!")
        self.collection1.close()
        self.collection2.close()
        e.accept()
Пример #8
0
    def setupUi(self):
        super().setupUi()

        class AddresRow(Row):
            columns = [
                ColumnSpec(LineEditColumn,
                           key_name="address",
                           label_name="Address")
            ]

        self.side_collection = SimpleCollection(filename="simple_side.db",
                                                row_classes=[AddresRow])
        """
        self.side_collection.clear()
        self.side_collection.new(AddresRow, {"address":"Main Street"})
        self.side_collection.new(AddresRow, {"address":"Side Street"})
        """

        def get_devices():
            return [("Sda device", "/dev/sda"), ("Sdb device", "/dev/sdb")]

        multichoice = [("Choice 1", "eka"), ("Choice 2", "toka")]
        mc_label = "MultiChoice"

        # mc_label = ""

        class TestRow_(Row):
            columns = [
                ColumnSpec(LineEditColumn,
                           key_name="firstname",
                           label_name="First Name"),
                ColumnSpec(LineEditColumn,
                           key_name="secondname",
                           label_name="Second Name"),
                ColumnSpec(LineEditColumn,
                           key_name="surname",
                           label_name="Surname"),
                ColumnSpec(ComboBoxColumn,
                           key_name="address",
                           label_name="Address",
                           collection=self.side_collection,
                           foreign_label_name="address"),
                ColumnSpec(ConstantComboBoxColumn,
                           key_name="device",
                           label_name="Device",
                           callback=get_devices),
                ColumnSpec(ConstantRadioButtonColumn,
                           key_name="multichoice",
                           label_name=mc_label,
                           list=multichoice)
                # foreigh_label_name = which key is taken for the drop-down list
            ]

        # TODO: see that initial values are loaded correctly from the db
        # TODO: ConstantRadioButtonColumn: rewrite createWidget

        self.collection = SimpleCollection(filename="simple_test.db",
                                           row_classes=[TestRow_])
        it = self.collection.get()
        for i in it:
            print(">>", i)

        class TestList_(List):
            def makeLabel(self, entry):
                return entry["firstname"] + " " + entry["surname"]

        class TestFormSet_(FormSet):
            row_classes = [
                TestRow,
                TestRow_,
            ]

        class TestEditFormSet_(EditFormSet):
            row_classes = [TestRow, TestRow_]

        self.lis = TestList_(collection=self.collection)
        self.formset = TestEditFormSet_(collection=self.collection)

        self.lis.widget.setParent(self.w)
        self.lay.addWidget(self.lis.widget)

        self.formset.widget.setParent(self.w)
        self.lay.addWidget(self.formset.widget)

        self.lis.widget.currentItemChanged.connect(
            self.formset.chooseForm_slot
        )  # inform formset about the item in question
        self.formset.signals.new_record.connect(
            self.lis.update_slot
        )  # inform list that a new entry has been added
Пример #9
0
    def define(self):
        """Define column patterns and databases
    """
        class FoodRow(Row):
            columns = [
                ColumnSpec(LineEditColumn, key_name="name", label_name="Name"),
                ColumnSpec(LineEditColumn,
                           key_name="price",
                           label_name="Price"),
                ColumnSpec(CheckBoxColumn,
                           key_name="spicy",
                           label_name="Is spicy")
            ]

        self.FoodRow = FoodRow

        self.food_collection = SimpleCollection(filename="food_test.db",
                                                row_classes=[self.FoodRow])

        class PersonRow(Row):
            columns = [
                ColumnSpec(LineEditColumn,
                           key_name="firstname",
                           label_name="First Name"),
                ColumnSpec(LineEditColumn,
                           key_name="surname",
                           label_name="Surname"),
                ColumnSpec(LineEditColumn,
                           key_name="address",
                           label_name="Address"),
                ColumnSpec(CheckBoxColumn,
                           key_name="married",
                           label_name="Is married")
            ]

        self.PersonRow = PersonRow

        class PersonRowExtended(Row):
            columns = [
                ColumnSpec(LineEditColumn,
                           key_name="firstname",
                           label_name="First Name"),
                ColumnSpec(LineEditColumn,
                           key_name="secondname",
                           label_name="Second Name"),
                ColumnSpec(LineEditColumn,
                           key_name="surname",
                           label_name="Surname"),
                ColumnSpec(LineEditColumn,
                           key_name="address",
                           label_name="Address"),
                # in the following, we're referring to self.food_collection and there, to the columns with keys "_id" and "name".  The ListEditColumn itself is a list of foreign_keys
                ColumnSpec(ListEditColumn,
                           key_name="foods",
                           label_name="Favorite foods",
                           collection=self.food_collection,
                           foreign_label_name="name")
            ]

        self.PersonRowExtended = PersonRowExtended

        self.collection = SimpleCollection(
            filename="simple_test.db",
            row_classes=[PersonRow, PersonRowExtended])

        class PersonList(List):
            def makeLabel(self, entry):
                try:
                    st = entry["firstname"] + " " + entry["surname"]
                except KeyError:
                    st = "?"
                return st

        self.PersonList = PersonList

        class FoodList(List):
            def makeLabel(self, entry):
                try:
                    st = entry["name"] + " (" + str(entry["price"]) + " EUR)"
                except KeyError:
                    st = "?"
                return st

        self.FoodList = FoodList
Пример #10
0
class DataModel:
    def __init__(self):
        self.define()
        self.initDB()

    def define(self):
        """Define column patterns and databases
    """
        class FoodRow(Row):
            columns = [
                ColumnSpec(LineEditColumn, key_name="name", label_name="Name"),
                ColumnSpec(LineEditColumn,
                           key_name="price",
                           label_name="Price"),
                ColumnSpec(CheckBoxColumn,
                           key_name="spicy",
                           label_name="Is spicy")
            ]

        self.FoodRow = FoodRow

        self.food_collection = SimpleCollection(filename="food_test.db",
                                                row_classes=[self.FoodRow])

        class PersonRow(Row):
            columns = [
                ColumnSpec(LineEditColumn,
                           key_name="firstname",
                           label_name="First Name"),
                ColumnSpec(LineEditColumn,
                           key_name="surname",
                           label_name="Surname"),
                ColumnSpec(LineEditColumn,
                           key_name="address",
                           label_name="Address"),
                ColumnSpec(CheckBoxColumn,
                           key_name="married",
                           label_name="Is married")
            ]

        self.PersonRow = PersonRow

        class PersonRowExtended(Row):
            columns = [
                ColumnSpec(LineEditColumn,
                           key_name="firstname",
                           label_name="First Name"),
                ColumnSpec(LineEditColumn,
                           key_name="secondname",
                           label_name="Second Name"),
                ColumnSpec(LineEditColumn,
                           key_name="surname",
                           label_name="Surname"),
                ColumnSpec(LineEditColumn,
                           key_name="address",
                           label_name="Address"),
                # in the following, we're referring to self.food_collection and there, to the columns with keys "_id" and "name".  The ListEditColumn itself is a list of foreign_keys
                ColumnSpec(ListEditColumn,
                           key_name="foods",
                           label_name="Favorite foods",
                           collection=self.food_collection,
                           foreign_label_name="name")
            ]

        self.PersonRowExtended = PersonRowExtended

        self.collection = SimpleCollection(
            filename="simple_test.db",
            row_classes=[PersonRow, PersonRowExtended])

        class PersonList(List):
            def makeLabel(self, entry):
                try:
                    st = entry["firstname"] + " " + entry["surname"]
                except KeyError:
                    st = "?"
                return st

        self.PersonList = PersonList

        class FoodList(List):
            def makeLabel(self, entry):
                try:
                    st = entry["name"] + " (" + str(entry["price"]) + " EUR)"
                except KeyError:
                    st = "?"
                return st

        self.FoodList = FoodList

    def initDB(self):
        """Write some entries to databases
    """
        self.collection.new(
            self.PersonRow, {
                "firstname": "Paavo",
                "surname": "Vayrynen",
                "address": "Koukkusaarentie 1",
                "married": True
            })
        self.collection.new(
            self.PersonRow, {
                "firstname": "Martti",
                "surname": "Ahtisaari",
                "address": "Lokkisaarentie 1",
                "married": True
            })

        # add some foods
        self.food_collection.new(self.FoodRow, {
            "name": "Hamburger",
            "price": 10,
            "spicy": False
        })
        self.food_collection.new(self.FoodRow, {
            "name": "Hotdog",
            "price": 50,
            "spicy": False
        })
        self.food_collection.new(self.FoodRow, {
            "name": "Freedom Fries",
            "price": 10,
            "spicy": False
        })
        self.food_collection.new(self.FoodRow, {
            "name": "Bacalao",
            "price": 100,
            "spicy": False
        })
        self.food_collection.new(self.FoodRow, {
            "name": "Piparra",
            "price": 1,
            "spicy": True
        })

        # get ids of some foods ..
        bacalao = list(
            self.food_collection.get(query={"name": "Bacalao"}))[0]["_id"]
        piparra = list(
            self.food_collection.get(query={"name": "Piparra"}))[0]["_id"]

        self.collection.new(
            self.PersonRowExtended, {
                "firstname": "Juho",
                "secondname": "Kustaa",
                "surname": "Paasikivi",
                "address": "Kontulankaari 1",
                "foods": []
            })
        self.collection.new(
            self.PersonRowExtended, {
                "firstname": "Esko",
                "secondname": "Iiro",
                "surname": "Seppänen",
                "address": "Mellunraitti 3",
                "foods": [bacalao, piparra]
            })
Пример #11
0
class DataModel:
    def __init__(self, directory="."):
        """DataModel ctor
        """
        self.directory = directory
        self.define()

    def __del__(self):
        # self.close()
        pass

    def close(self):
        # print("close: ",self.area_rights_collection)
        for collection in self.collections:
            collection.close()

    def clearAll(self):
        # print("DataModel", "clearAll")
        self.clearCameraCollection()
        self.config_collection.clear()
        self.valkkafs_collection.clear()
        self.layout_collection.clear()

    def saveAll(self):
        for collection in self.collections:
            collection.save()

    def clearCameraCollection(self):
        self.camera_collection.clear()
        for i in range(1, constant.max_devices + 1):
            self.camera_collection.new(EmptyRow, {"slot": i})

    def checkCameraCollection(self):
        c = 0
        for c, device in enumerate(self.camera_collection.get()):
            pass
        if (c != constant.max_devices - 1):
            return False
        return True

    def autoGenerateCameraCollection(self, base_address, nstart, n, port, tail,
                                     username, password):
        """
        :param:  base_address    str, e.g. "192.168.1"
        :param:  nstart          int, e.g. 24
        :param:  n               int, how many ips generated 
        """
        self.camera_collection.clear()
        self.camera_collection.save()
        cc = nstart
        for i in range(1, min((n + 1, constant.max_devices + 1))):
            print(i)
            self.camera_collection.new(
                RTSPCameraRow, {
                    "slot": i,
                    "address": base_address + "." + str(cc),
                    "username": username,
                    "password": password,
                    "port": port,
                    "tail": tail,
                    "subaddress_main": "",
                    "live_main": True,
                    "rec_main": False,
                    "subaddress_sub": "",
                    "live_sub": False,
                    "rec_sub": False
                })
            cc += 1

        print("Camera addesses now:")
        for c, device in enumerate(self.camera_collection.get()):
            print(c + 1, RTSPCameraRow.getMainAddressFromDict(device))

        for i in range(n + 1, constant.max_devices + 1):
            self.camera_collection.new(EmptyRow, {"slot": i})

        self.camera_collection.save()

        print("Camera collection now:")
        for c, device in enumerate(self.camera_collection.get()):
            print(c + 1, device)

    def purge(self):
        """For migrations / cleanup.  Collections should be in correct order.
        """
        for collection in self.collections:
            # print("purging",collection)
            collection.purge()

    def define(self):
        """Define column patterns and collections
        """
        self.collections = []

        self.camera_collection = \
            SimpleCollection(filename=os.path.join(self.directory, "devices.dat"),
                             row_classes=[
                    EmptyRow,
                    RTSPCameraRow,
                    USBCameraRow
                ]
            )
        self.collections.append(self.camera_collection)

        self.config_collection = \
            SimpleCollection(filename=os.path.join(self.directory, "config.dat"),
                row_classes=[  # we could dump here all kinds of info related to different kind of configuration forms
                    MemoryConfigRow
                ]
            )
        self.collections.append(self.config_collection)

        self.valkkafs_collection = \
            SimpleCollection(filename=os.path.join(self.directory, "valkkafs.dat"),
                row_classes=[
                    ValkkaFSConfigRow
                ]
            )
        self.collections.append(self.valkkafs_collection)
        """
        self.layout_collection = \
            SimpleCollection(filename=os.path.join(self.directory, "layout.dat"),
                row_classes=[
                    VideoContainerNxMRow,
                    PlayVideoContainerNxMRow,
                    CameraListWindowRow,
                    MainWindowRow
                ]
            )
        """
        self.layout_collection = \
            SimpleCollection(filename=os.path.join(self.directory, "layout.dat"),
                row_classes=[
                    LayoutContainerRow
                ]
            )

        self.collections.append(self.layout_collection)

    def getDeviceList(self):
        return DeviceList(collection=self.camera_collection)

    def getDeviceListAndForm(self, parent):
        device_list = DeviceList(collection=self.camera_collection)
        device_form = SlotFormSet(collection=self.camera_collection)
        return ListAndForm(device_list,
                           device_form,
                           title="Camera configuration",
                           parent=parent)

    def getConfigForm(self):
        return MemoryConfigForm(row_class=MemoryConfigRow,
                                collection=self.config_collection)

    def getValkkaFSForm(self):
        return ValkkaFSForm(row_class=ValkkaFSConfigRow,
                            collection=self.valkkafs_collection)

    def getRowsById(self, query):
        rows = self.camera_collection.get(query)
        rows_by_id = {}
        for row in rows:
            rows_by_id[row["_id"]] = row

        return rows_by_id

    def getDevicesById(self):  # , query):
        """
        rows = self.camera_collection.get(query)
        devices_by_id = {}
        for row in rows:
            row.pop("classname")
            device = RTSPCameraDevice(**row)
            devices_by_id[device._id] = device
        return devices_by_id
        """
        rows = self.camera_collection.get()
        devices_by_id = {}
        for row in rows:
            classname = row.pop("classname")
            if (classname == "RTSPCameraRow"):
                device = RTSPCameraDevice(**row)
            elif (classname == "USBCameraRow"):
                device = USBCameraDevice(**row)
            else:
                device = None
            if (device):
                devices_by_id[device._id] = device
        return devices_by_id

    def writeDefaultValkkaFSConfig(self):
        self.valkkafs_collection.new(
            ValkkaFSConfigRow,
            {
                # "dirname"    : default.valkkafs_config["dirname"], # not written to db for the moment
                "n_blocks": default.get_valkkafs_config()["n_blocks"],
                "blocksize": default.get_valkkafs_config()["blocksize"],
                "fs_flavor": default.get_valkkafs_config()["fs_flavor"],
                "record": default.get_valkkafs_config()["record"],
                "partition_uuid":
                default.get_valkkafs_config()["partition_uuid"]
            })

    def writeDefaultMemoryConfig(self):
        self.config_collection.new(MemoryConfigRow,
                                   default.get_memory_config())
Пример #12
0
    columns = [
        ColumnSpec(LineEditColumn,
                   key_name="firstname",
                   label_name="First Name"),
        ColumnSpec(LineEditColumn,
                   key_name="secondname",
                   label_name="Second Name"),
        ColumnSpec(LineEditColumn, key_name="surname", label_name="Surname"),
        ColumnSpec(LineEditColumn, key_name="address", label_name="Address")
    ]


"""<rtf>
Create collection.  SimpleCollection is a simple test database (just a python dictionary), but the interface to MongoDB works with the same API
<rtf>"""
collection = SimpleCollection(filename="simple_test.db",
                              row_classes=[PersonRow, PersonRowExtended])
"""<rtf>
Next we create a list of database entries.  The List class is Row agnostic.  It only knows how to create a label, using a Row entry.  The only method we need to overwrite is the one used to create a label:
<rtf>"""


class PersonList(List):
    def makeLabel(self, entry):
        try:
            st = entry["firstname"] + " " + entry["surname"]
        except KeyError:
            st = "?"
        return st


"""<rtf>
Пример #13
0
from cute_mongo_forms.row import ColumnSpec, Row
from cute_mongo_forms.container import List, FormSet, EditFormSet, PermissionFormSet
from cute_mongo_forms.db import SimpleCollection
"""<rtf>
Create the column patters (Rows) for each collection.
<rtf>"""


class PersonRow(Row):
    columns = [
        ColumnSpec(LineEditColumn, key_name="name", label_name="First Name"),
        ColumnSpec(LineEditColumn, key_name="surname", label_name="Last Name")
    ]


person_collection = SimpleCollection(filename="persons.db",
                                     row_classes=[PersonRow])
person_collection.clear()


class CarRow(Row):
    columns = [
        ColumnSpec(LineEditColumn, key_name="brand", label_name="Brand"),
        ColumnSpec(LineEditColumn, key_name="year", label_name="Year")
    ]


car_collection = SimpleCollection(filename="cars.db", row_classes=[CarRow])
car_collection.clear()
"""<rtf>
Here we are referencing to foreign keys.  The *ForeignKeyColumn* column type is a special column that's not visualized in the form widget ("label_name" is missing).  It's only used for referencing records in other collections:
<rtf>"""
Пример #14
0
    def defineSchema(self):
        """Define column patterns and databases
    """
        class FoodRow(Row):
            columns = [
                ColumnSpec(LineEditColumn, key_name="name", label_name="Name"),
                ColumnSpec(LineEditColumn,
                           key_name="price",
                           label_name="Price"),
                ColumnSpec(CheckBoxColumn,
                           key_name="spicy",
                           label_name="Is spicy")
            ]

        self.FoodRow = FoodRow

        self.food_collection = SimpleCollection(filename="food_test.db",
                                                row_classes=[self.FoodRow])

        class PersonRow(Row):
            columns = [
                ColumnSpec(LineEditColumn,
                           key_name="firstname",
                           label_name="First Name"),
                ColumnSpec(LineEditColumn,
                           key_name="surname",
                           label_name="Surname"),
                ColumnSpec(LineEditColumn,
                           key_name="address",
                           label_name="Address"),
                ColumnSpec(CheckBoxColumn,
                           key_name="married",
                           label_name="Is married")
            ]

        self.PersonRow = PersonRow

        class PersonRowExtended(Row):
            columns = [
                ColumnSpec(LineEditColumn,
                           key_name="firstname",
                           label_name="First Name"),
                ColumnSpec(LineEditColumn,
                           key_name="secondname",
                           label_name="Second Name"),
                ColumnSpec(LineEditColumn,
                           key_name="surname",
                           label_name="Surname"),
                ColumnSpec(LineEditColumn,
                           key_name="address",
                           label_name="Address"),
                # in the following, we're referring to self.food_collection and there, to the columns with keys "_id" and "name".  The ListEditColumn itself is a list of foreign_keys
                ColumnSpec(ListEditColumn,
                           key_name="foods",
                           label_name="Favorite foods",
                           collection=self.food_collection,
                           foreign_label_name="name")
            ]

        self.PersonRowExtended = PersonRowExtended

        self.collection = SimpleCollection(
            filename="simple_test.db",
            row_classes=[self.PersonRow, self.PersonRowExtended])
Пример #15
0
class DataModel:

    # Device collection: RTSP Cameras, SDP files, etc.

    class EmptyRow(Row):
        name = "<Empty>"
        columns = [
            ColumnSpec(ConstantIntegerColumn,
                       key_name="slot",
                       label_name="Slot"),
        ]

        def isActive(self):
            """Is this row class visible in the form drop-down menu
            """
            return True

    class USBCameraRow(Row):
        name = "H264 USB Camera"
        columns = [
            ColumnSpec(ConstantIntegerColumn,
                       key_name="slot",
                       label_name="Slot"),
            ColumnSpec(USBCameraColumn,
                       key_name="address",
                       label_name="Device")
        ]

        def isActive(self):
            """Show only if there are USB cams
            """
            return len(tools.getH264V4l2()) > 0

    class RTSPCameraRow(Row):
        name = "RTSP Camera"
        columns = [
            ColumnSpec(ConstantIntegerColumn,
                       key_name="slot",
                       label_name="Slot"),
            ColumnSpec(IPv4AddressColumn,
                       key_name="address",
                       label_name="IP Address"),
            ColumnSpec(LineEditColumn,
                       key_name="username",
                       label_name="Username"),
            ColumnSpec(LineEditColumn,
                       key_name="password",
                       label_name="Password"),
            ColumnSpec(LineEditColumn, key_name="port", label_name="Port"),
            ColumnSpec(LineEditColumn, key_name="tail", label_name="Tail"),
            ColumnSpec(LineEditColumn,
                       key_name="subaddress_main",
                       label_name="Subaddress"),
            ColumnSpec(CheckBoxColumn,
                       key_name="live_main",
                       label_name="Use stream",
                       def_value=True),
            ColumnSpec(CheckBoxColumn,
                       key_name="rec_main",
                       label_name="Record stream",
                       def_value=False),
            ColumnSpec(LineEditColumn,
                       key_name="subaddress_sub",
                       label_name="Subaddress"),
            ColumnSpec(CheckBoxColumn,
                       key_name="live_sub",
                       label_name="Use stream",
                       def_value=False),
            ColumnSpec(CheckBoxColumn,
                       key_name="rec_sub",
                       label_name="Record stream",
                       def_value=False)
        ]

        def isActive(self):
            return True

        @classmethod
        def getMainAddressFromDict(cls, dic):
            st = "rtsp://"
            st += dic["username"] + ":"
            st += dic["password"] + "@"
            st += dic["address"]
            if (dic["port"].strip() != ""):
                st += ":" + dic["port"].strip()
            if (len(dic["tail"]) > 0):
                st += "/" + dic["tail"]
            if (len(dic["subaddress_main"]) > 0):
                st += "/" + dic["subaddress_main"]
            return st

        @classmethod
        def getSubAddressFromDict(cls, dic):
            st = "rtsp://"
            st += dic["username"] + ":"
            st += dic["password"] + "@"
            st += dic["address"]
            if (dic["port"].strip() != ""):
                st += ":" + dic["port"].strip()
            if (len(dic["tail"]) > 0):
                st += "/" + dic["tail"]
            if (len(dic["subaddress_main"]) > 0):
                st += "/" + dic["subaddress_sub"]
            return st

        def makeWidget(self):
            """Subclassed from Row : custom form.  Add a summary RTSP address in the end of the form, etc.
            """

            # super().makeWidget() # do all by hand

            class FormWidget(QtWidgets.QWidget):
                """Just a QWidget that sends a signal when its shown
                """
                class Signals(QtCore.QObject):
                    show = QtCore.Signal()

                def __init__(self, parent=None):
                    super().__init__(parent)
                    self.signals = self.Signals()

                def showEvent(self, e):
                    self.signals.show.emit()
                    e.accept()

            self.widget = FormWidget()
            self.lay = QtWidgets.QGridLayout(self.widget)

            cc = 0
            self.placeWidget(cc, "slot")
            cc += 1
            self.placeWidget(cc, "address")
            cc += 1
            self.placeWidget(cc, "username")
            cc += 1
            self.placeWidget(cc, "password")
            cc += 1
            self.placeWidget(cc, "port")
            cc += 1
            self.placeWidget(cc, "tail")
            cc += 1

            # Mainstream
            self.label_mainstream = QtWidgets.QLabel("Mainstream", self.widget)
            self.label_mainstream.setStyleSheet(style.form_highlight)
            self.placeWidgetPair(cc, (self.label_mainstream, None))
            cc += 1
            self.placeWidget(cc, "subaddress_main")
            cc += 1
            # complete RTSP address
            self.label_mainstream_address = QtWidgets.QLabel(
                "RTSP address", self.widget)
            self.mainstream_address = QtWidgets.QLabel("", self.widget)
            self.placeWidgetPair(
                cc, (self.label_mainstream_address, self.mainstream_address))
            cc += 1
            # live and rec
            self.placeWidget(cc, "live_main")
            cc += 1
            self.placeWidget(cc, "rec_main")
            cc += 1

            # Substream
            self.label_substream = QtWidgets.QLabel("Substream", self.widget)
            self.label_substream.setStyleSheet(style.form_highlight)
            self.placeWidgetPair(cc, (self.label_substream, None))
            cc += 1
            self.placeWidget(cc, "subaddress_sub")
            cc += 1
            # complete RTSP address
            self.label_substream_address = QtWidgets.QLabel(
                "RTSP address", self.widget)
            self.substream_address = QtWidgets.QLabel("", self.widget)
            self.placeWidgetPair(
                cc, (self.label_substream_address, self.substream_address))
            cc += 1
            # live and rec
            self.placeWidget(cc, "live_sub")
            cc += 1
            self.placeWidget(cc, "rec_sub")
            cc += 1
            """ # definitely NOT here!
            # self.copy_label = QtWidgets.QLabel("Copy this camera", self.widget)
            self.copy_button = QtWidgets.QPushButton("Copy", self.widget)
            self.placeWidgetPair(cc, (self.copy_button, None))
            self.copy_button.clicked.connect(self.copy_slot)
            """

            self.connectNotifications()

            def rec_main_clicked():
                if not self["live_main"].widget.isChecked(
                ):  # rec requires live
                    print("live_main is NOT checked")
                    self["rec_main"].widget.setChecked(False)
                if self["rec_main"].widget.isChecked(
                ):  # rec main excludes rec sub
                    self["rec_sub"].widget.setChecked(False)

            def rec_sub_clicked():
                if not self["live_sub"].widget.isChecked(
                ):  # rec requires live
                    print("live_sub is NOT checked")
                    self["rec_sub"].widget.setChecked(False)
                if self["rec_sub"].widget.isChecked(
                ):  # rec sub excludes rec main
                    self["rec_main"].widget.setChecked(False)

            self["rec_main"].widget.clicked.connect(rec_main_clicked)
            self["rec_sub"].widget.clicked.connect(rec_sub_clicked)
            self.widget.signals.show.connect(self.show_slot)

            # TODO: remove these restrictions once functional:
            self["subaddress_main"].widget.setEnabled(False)
            self["subaddress_sub"].widget.setEnabled(False)
            self["live_main"].widget.setEnabled(False)
            self["rec_main"].widget.setEnabled(False)
            self["live_sub"].widget.setEnabled(False)
            self["rec_sub"].widget.setEnabled(False)

        """
        def get(self, collection, _id):
            #Subclassed from Row : Load one entry from db to QtWidgets
            super().get(collection, _id)
            self.update_notify_slot()
        """

        def getMainAddress(self):
            # e.g. : rtsp://admin:[email protected]/tail
            dic = self.__collect__()  # returns a dictionary of column values
            return DataModel.RTSPCameraRow.getMainAddressFromDict(dic)

        def getSubAddress(self):
            # e.g. : rtsp://admin:[email protected]/tail
            dic = self.__collect__()  # returns a dictionary of column values
            return DataModel.RTSPCameraRow.getSubAddressFromDict(dic)

        def update_notify_slot(self):
            """This slot gets pinged always when the form fields have been updated
            """
            # pass
            # print("RTSPCameraRow: value changed")
            self.mainstream_address.setText(self.getMainAddress())
            self.substream_address.setText(self.getSubAddress())
            # self.copy_button.setEnabled(False) # must save before can copy # nopes ..

            # rec main and sub exclude each other
            # rec requires live

        def show_slot(self):
            self.mainstream_address.setText(self.getMainAddress())
            self.substream_address.setText(self.getSubAddress())

    class RTSPCameraDevice:
        """Device class used in drag'n'drop.  Copies the members of RTSPCameraRow
        """

        parameter_defs = {
            "_id": int,
            "slot": int,
            "address": str,
            "username": str,
            "password": str,
            "port": (str, ""),
            "tail": (str, ""),
            "subaddress_main": (str, ""),
            "live_main": (bool, True),
            "rec_main": (bool, False),
            "subaddress_sub": (str, ""),
            "live_sub": (bool, False),
            "rec_sub": (bool, False)
        }

        def __init__(self, **kwargs):
            # auxiliary string for debugging output
            self.pre = self.__class__.__name__ + " : "
            # check for input parameters, attach them to this instance as
            # attributes
            parameterInitCheck(DataModel.RTSPCameraDevice.parameter_defs,
                               kwargs, self)

        def __eq__(self, other):
            return self._id == other._id

        def getMainAddress(self):
            st = "rtsp://" + self.username + ":" + self.password + "@" + self.address
            if (len(self.tail) > 0):
                st += "/" + self.tail
            if (len(self.subaddress_main) > 0):
                st += "/" + self.subaddress_main
            return st

        def getSubAddress(self):
            st = "rtsp://" + self.username + ":" + self.password + "@" + self.address
            if (len(self.tail) > 0):
                st += "/" + self.tail
            if (len(self.subaddress_sub) > 0):
                st += "/" + self.subaddress_main
            return st

        def getLabel(self):
            st = "rtsp://" + self.address
            if (len(self.tail) > 0):
                st += "/" + self.tail
            return st

        # the following methods give the true slot numbers used by Valkka
        # one slot for main, sub and recorded stream per camera
        # 1..3, 4..6, 7..9, etc.
        def getLiveMainSlot(self):
            return (self.slot - 1) * 3 + 1

        def getLiveSubSlot(self):
            return (self.slot - 1) * 3 + 2

        def getRecSlot(self):
            return (self.slot - 1) * 3 + 3

    class USBCameraDevice:
        """Device class used in drag'n'drop.  Copies the members of RTSPCameraRow
        """

        parameter_defs = {"_id": int, "slot": int, "address": str}

        def __init__(self, **kwargs):
            # auxiliary string for debugging output
            self.pre = self.__class__.__name__ + " : "
            # check for input parameters, attach them to this instance as
            # attributes
            parameterInitCheck(DataModel.USBCameraDevice.parameter_defs,
                               kwargs, self)

        def __eq__(self, other):
            return self._id == other._id

        def getMainAddress(self):
            return self.address

        def getSubAddress(self):
            return self.address

        def getLabel(self):
            return "usb:" + self.address

        # the following methods give the true slot numbers used by Valkka
        # one slot for main, sub and recorded stream per camera
        # 1..3, 4..6, 7..9, etc.
        def getLiveMainSlot(self):
            return (self.slot - 1) * 3 + 1

        def getLiveSubSlot(self):
            return (self.slot - 1) * 3 + 2

        def getRecSlot(self):
            return (self.slot - 1) * 3 + 3

    # A general collection for misc. stuff: configuration, etc.

    class MemoryConfigRow(Row):

        columns = [
            ColumnSpec(IntegerColumn,
                       key_name="msbuftime",
                       label_name="Buffering time (ms)",
                       min_value=50,
                       max_value=1000,
                       def_value=default.memory_config["msbuftime"]),
            ColumnSpec(IntegerColumn,
                       key_name="n_720p",
                       label_name="Number of 720p streams",
                       min_value=0,
                       max_value=1024,
                       def_value=default.memory_config["n_720p"]),
            ColumnSpec(IntegerColumn,
                       key_name="n_1080p",
                       label_name="Number of 1080p streams",
                       min_value=0,
                       max_value=1024,
                       def_value=default.memory_config["n_1080p"]),
            ColumnSpec(IntegerColumn,
                       key_name="n_1440p",
                       label_name="Number of 2K streams",
                       min_value=0,
                       max_value=1024,
                       def_value=default.memory_config["n_1440p"]),
            ColumnSpec(IntegerColumn,
                       key_name="n_4K",
                       label_name="Number of 4K streams",
                       min_value=0,
                       max_value=1024,
                       def_value=default.memory_config["n_4K"]),
            ColumnSpec(CheckBoxColumn,
                       key_name="bind",
                       label_name="Bind Valkka threads to cores",
                       def_value=default.memory_config["bind"])
        ]

        def getNFrames(self, key):
            """Get number of necessary frames for certain camera resolution

            :param key:   n720p, n1080p, etc.
            """

            buftime = self["buftime"]
            ncam = self[key]

            # assume 25 fps cameras
            return int((buftime / 1000) * 25 * ncam)

    # *** Simple lists ***

    class DeviceList(List):
        class SortableWidgetItem(QtWidgets.QListWidgetItem):
            """A sortable listwidget item class
            """
            def __init__(self):
                super().__init__()
                # self.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)

            def __lt__(self, other):
                try:
                    return int(self.slot) < int(other.slot)
                except Exception:
                    return QListWidgetItem.__lt__(self, other)

        def makeWidget(self):
            super().makeWidget()
            # self.widget.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)

        def update(self):
            # Fills the root and subwidgets with data.
            self.widget.clear()
            self.items_by_id = {}
            for entry in self.collection.get():
                item = self.createItem()
                label = self.makeLabel(entry)
                item.setText(label)
                item._id = entry["_id"]
                item.slot = int(entry["slot"])  # add an extra attribute
                try:
                    item.classname = entry["classname"]
                except KeyError:
                    raise (
                        KeyError("Your database contains crap.  Do a purge"))
                self.items_by_id[item._id] = item
                self.widget.addItem(item)
            self.widget.sortItems()
            self.widget.setMinimumWidth(self.widget.sizeHintForColumn(0))

        def createItem(self):
            """Overwrite in child classes to create custom items (say, sortable items, etc.)
            """
            return self.SortableWidgetItem()

        def makeLabel(self, entry):
            # print("DataModel : makeLabel :", entry["classname"])
            st = str(entry["slot"])
            if (entry["classname"] == "RTSPCameraRow"):
                st += " RTSP (" + entry["address"] + ")"
            elif (entry["classname"] == "USBCameraRow"):
                st += " USB (" + str(
                    entry["address"]) + ")"  # could be NoneType
            return st

    # *** A stand-alone form for MemoryConfigRow ***

    class MemoryConfigForm(SimpleForm):
        class Signals(QtCore.QObject):
            save = QtCore.Signal()

        parameter_defs = {"row_class": RowWatcher, "collection": None}

        def __init__(self, **kwargs):
            super().__init__(**kwargs)
            self.signals = self.Signals()
            self.load()

        def makeWidget(self):
            super().makeWidget()

            self.button_row = QtWidgets.QWidget(self.widget)
            self.button_lay = QtWidgets.QHBoxLayout(self.button_row)
            self.lay.addWidget(self.button_row)

            self.reset_button = QtWidgets.QPushButton("Reset", self.button_row)
            self.save_button = QtWidgets.QPushButton("Save", self.button_row)
            self.button_lay.addWidget(self.reset_button)
            self.button_lay.addWidget(self.save_button)

            self.info_label = QtWidgets.QLabel(
                "Saving restarts all Valkka services", self.widget)
            self.lay.addWidget(self.info_label)

            self.reset_button.clicked.connect(self.row_instance.clear)
            self.save_button.clicked.connect(self.save_slot)

        def load(self):
            try:
                el = next(
                    self.collection.get(
                        {"classname": DataModel.MemoryConfigRow.__name__}))
            except StopIteration:
                print(self.pre, "no row!")
            else:
                print(self.pre, "reading saved")
                self.row_instance.get(self.collection, el["_id"])

        def save_slot(self):
            try:
                el = next(
                    self.collection.get(
                        {"classname": DataModel.MemoryConfigRow.__name__}))
            except StopIteration:
                print(self.pre, "new row")
                _id = self.row_instance.new(
                    self.collection)  # create a new instance
            else:
                print(self.pre, "update row")
                _id = el["_id"]
                self.row_instance.update(self.collection, _id)

            self.signals.save.emit()

    def __init__(self, directory="."):
        self.directory = directory
        self.define()

    def __del__(self):
        # self.close()
        pass

    def close(self):
        # print("close: ",self.area_rights_collection)
        for collection in self.collections:
            collection.close()

    def clearAll(self):
        # print("DataModel", "clearAll")
        self.clearCameraCollection()
        self.config_collection.clear()

    def saveAll(self):
        self.camera_collection.save()
        self.config_collection.save()

    def clearCameraCollection(self):
        self.camera_collection.clear()
        for i in range(1, constant.max_devices + 1):
            self.camera_collection.new(self.EmptyRow, {"slot": i})

    def checkCameraCollection(self):
        c = 0
        for c, device in enumerate(self.camera_collection.get()):
            pass
        if (c != constant.max_devices - 1):
            return False
        return True

    def autoGenerateCameraCollection(self, base_address, nstart, n, port, tail,
                                     username, password):
        """
        :param:  base_address    str, e.g. "192.168.1"
        :param:  nstart          int, e.g. 24
        :param:  n               int, how many ips generated 
        """
        self.camera_collection.clear()
        self.camera_collection.save()
        cc = nstart
        for i in range(1, min((n + 1, constant.max_devices + 1))):
            print(i)
            self.camera_collection.new(
                self.RTSPCameraRow, {
                    "slot": i,
                    "address": base_address + "." + str(cc),
                    "username": username,
                    "password": password,
                    "port": port,
                    "tail": tail,
                    "subaddress_main": "",
                    "live_main": True,
                    "rec_main": False,
                    "subaddress_sub": "",
                    "live_sub": False,
                    "rec_sub": False
                })
            cc += 1

        print("Camera addesses now:")
        for c, device in enumerate(self.camera_collection.get()):
            print(c + 1, self.RTSPCameraRow.getMainAddressFromDict(device))

        for i in range(n + 1, constant.max_devices + 1):
            self.camera_collection.new(self.EmptyRow, {"slot": i})

        self.camera_collection.save()

        print("Camera collection now:")
        for c, device in enumerate(self.camera_collection.get()):
            print(c + 1, device)

    def purge(self):
        """For migrations / cleanup.  Collections should be in correct order.
        """
        for collection in self.collections:
            # print("purging",collection)
            collection.purge()

    def define(self):
        """Define column patterns and collections
        """
        self.collections = []

        self.camera_collection = \
            SimpleCollection(filename=os.path.join(self.directory, "devices.dat"),
                             row_classes=[
                DataModel.EmptyRow,
                DataModel.RTSPCameraRow,
                DataModel.USBCameraRow
            ]
            )
        self.collections.append(self.camera_collection)

        self.config_collection = \
            SimpleCollection(filename=os.path.join(self.directory, "config.dat"),
                             row_classes=[  # we could dump here all kinds of info related to different kind of configuration forms
                DataModel.MemoryConfigRow
            ]
            )
        self.collections.append(self.config_collection)

    def getDeviceList(self):
        return DataModel.DeviceList(collection=self.camera_collection)

    def getDeviceListAndForm(self, parent):
        device_list = DataModel.DeviceList(collection=self.camera_collection)
        device_form = SlotFormSet(collection=self.camera_collection)
        return ListAndForm(device_list,
                           device_form,
                           title="Camera configuration",
                           parent=parent)

    def getConfigForm(self):
        return DataModel.MemoryConfigForm(row_class=DataModel.MemoryConfigRow,
                                          collection=self.config_collection)

    def getRowsById(self, query):
        rows = self.camera_collection.get(query)
        rows_by_id = {}
        for row in rows:
            rows_by_id[row["_id"]] = row

        return rows_by_id

    def getDevicesById(self):  # , query):
        """
        rows = self.camera_collection.get(query)
        devices_by_id = {}
        for row in rows:
            row.pop("classname")
            device = DataModel.RTSPCameraDevice(**row)
            devices_by_id[device._id] = device
        return devices_by_id
        """
        rows = self.camera_collection.get()
        devices_by_id = {}
        for row in rows:
            classname = row.pop("classname")
            if (classname == "RTSPCameraRow"):
                device = DataModel.RTSPCameraDevice(**row)
            elif (classname == "USBCameraRow"):
                device = DataModel.USBCameraDevice(**row)
            else:
                device = None
            if (device):
                devices_by_id[device._id] = device
        return devices_by_id