Modules ======= The ``Modules``-class provides access to the database-modules. In scriptor, there's a preconfigured instance under the name ``modules`` (all lowercase) connected to your viur backend. Accessing a module is simply done by calling ``get_module``. Here's an example to retrieve all users and print them: .. code-block:: python #### scriptor #### from viur.scriptor import * async def main(): users = await modules.get_module("user") async for user in users.list(): print(user) Depending on the type of module, the result of ``get_module`` differs. It can return a ``ListModule``, a ``TreeModule`` or a ``SingletonModule``. The methods available in all of them are ``view``, ``edit``, ``structure`` and ``preview``. ``TreeModule`` and ``ListModule`` additionaly have ``list``, ``add``, ``delete`` and ``for_each``. In addition to that, ``TreeModule`` also has ``list_root_nodes`` and ``move``. ``TreeModule`` and ``ListModule`` also need an extra parameter for methods, that interact with the database. For ``ListModule``, this is ``group``. The group parameter filters only records that belong to that group and also potentially modifies the returned model (i.e. if you're selling kitchen supplies, pans might have a diameter, which would be unused for knives). For ``TreeModule``, the extra parameter is ``skel_type``. It can have one of two values: ``node`` or ``leaf``. This determines what parts of the tree will be returned (i.e. for scriptor-scripts, scripts are leaves and the folders are nodes). Since examples are specific to the database and its configuration, the first ones assume you have a module called "example" that has at least the fields "name" and "sortindex". Here's how you'd create five new records with the name test and sortindex ranging from 1 to 5. .. code-block:: python #### scriptor #### from viur.scriptor import * async def main(): example_entries_to_add = 5 example = await modules.get_module("example") for i in range(example_entries_to_add): ProgressBar.set(i/example_entries_to_add*100, i, example_entries_to_add, str(i)) await example.add({"name": "test", "sortindex": i+1}) ProgressBar.unset() The next example shows, how to get all records with the name "test" and rename one of them. It also shows the number of records named "test" before and after the edit. .. code-block:: python #### scriptor #### from viur.scriptor import * async def main(): example = await modules.get_module("example") test = await gather_async_iterator(example.list(params={"name": "test"})) print(f"""Number of records with name "test": {len(test)}""") try: print(f"""The record we'll edit:\n{test[0]}""") test_key = test[0]["key"] except IndexError: print("""Nothing to do, there are not records with the name "test" left.""") return print(f"""Key of the record we'll edit: {test_key}""") await example.edit(key=test_key, params={"name": "test_edited"}) test_after_edit = await gather_async_iterator(example.list(params={"name": "test"})) print(f"""Number of records with name "test" after editing: {len(test_after_edit)}""") edited_test = await example.view(key=test_key) print(f"""The edited record:\n{edited_test}""") After creating and renaming test records, you might want to delete them from the database. This example shows how to delete all records with the name "test_edited": .. code-block:: python #### scriptor #### from viur.scriptor import * async def main(): example = await modules.get_module("example") test = await gather_async_iterator(example.list(params={"name": "test_edited"})) print(f"""Number of records with name "test_edited": {len(test)}""") for t in test: print(f"""deleting record with id {t["key"]}""") res = await example.delete(key=t["key"]) test_after_deletes = await gather_async_iterator( example.list(params={"name": "test_edited"}) ) print(f"""Number of records with name "test_edited" after deletion:""" f"""{len(test_after_deletes)}""") As a final example, here's how to export all scriptor-scripts to a compressed zip-file. We won't demonstrate how to modify or delete scripts here. .. code-block:: python #### scriptor #### from viur.scriptor import * from io import BytesIO from zipfile import ZipFile, ZIP_DEFLATED async def main(): script = await modules.get_module("script") scriptleaves = await gather_async_iterator(script.list(params={"skelType": "leaf"})) bio = BytesIO() script_count = len(scriptleaves) with ZipFile(bio, "w", compression=ZIP_DEFLATED, compresslevel=9) as z: for n, s in enumerate(scriptleaves): name = s["name"] ProgressBar.set(n/script_count*100, n, script_count, name) try: z.writestr(s["path"], s["script"]) except KeyError: z.writestr(name, s["script"]) ProgressBar.unset() bio.seek(0) zip_bytes = bio.read() bio.close() zipname = f"""ScriptorScripts.zip""" print(f"""downloading "{zipname}" ({len(zip_bytes):_} b)""") out_file = File.from_bytes(zip_bytes, zipname) out_file.download() print("...done")