nostalgic


Namenostalgic JSON
Version 1.4.1 PyPI version JSON
download
home_pagehttps://codeberg.org/excalamus/nostalgic
SummaryA drop-in configuration module to save and restore end-user and application settings
upload_time2022-06-21 00:41:26
maintainer
docs_urlNone
authorMatt Trzcinski
requires_python>=3.6
license
keywords settings configuration configure config development application
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            > ***Savor what you feel and what you see / Things that may not seem important now / But may be tomorrow***
>
> *–Chuck Schuldiner*

# Nostalgic
A drop-in configuration module to save and restore end-user and
application settings.

- No meta-files
- Built using only the Python standard library
- Handle UI syncing

# Install
```python
pip install nostalgic
```

# Motivation
Many configuration packages themselves require configuration files.
This often is extraneous.

Others provide a non-Pythonic API which hinders comprehension.  For
example, QSettings looks like

```python
# bad
self.settings.setValue("my_tracked_variable", value)
```

and

```python
# bad
self.settings.value("my_tracked_variable", DEFAULT_SETTINGS["my_tracked_variable"])
```

How you work with a variable depends on whether or not it's been
touched by Qt.

With Nostalgic, these calls look simply like

```python
# good
self.settings.my_tracked_value = value
```

and

```python
# good
self.settings.my_tracked_value
```

Furthermore, most applications likely require only a single
configuration.  Nostalgic uses a Configuration singleton for this
reason.  Instantiate a Configuration and the next time one is created,
it will be a reference to the already extant Configuration.  This
means explicit references to the Configuration don't need to be passed
around.

# Quick Start
A Configuration is a collection of Settings.

- Use a dot to get the Setting value (like an attribute)
- Settings can have a default initial value
- `write()` settings to disk and `read()` them back in

```python
# basic usage
import os   # needed only for demonstration
import sys  # needed only for demonstration
import nostalgic


if __name__ == '__main__':
    # create configuration in current directory
    cfg = nostalgic.Configuration("sample_config")

    # declare a setting 'foo' with initial value
    cfg.add_setting("foo", default="bar")

    print(cfg.foo)  # "bar"

    # change the value
    cfg.foo = "baz"

    try:
        # second run
        cfg.read()
        print("Config just read")
        print(cfg.foo)  # "baz"
        os.remove(cfg.config_file)
        if not os.path.exists(cfg.config_file):
            print("Removed config file")
    except FileNotFoundError:
        # first run, no config yet
        cfg.write()
        print("Wrote config")
        sys.exit()

```

```sh
$ python3 "/home/ahab/Projects/nostalgic/scratch/sample1.py"
bar
Wrote config

$ python3 "/home/ahab/Projects/nostalgic/scratch/sample1.py"
bar
Config just read
baz
Removed config file
```

## Advanced: coordinate a configuration with the UI
Optional setter and getter functions handle updating other parts of your code.

```python
# demonstrate getting on write() and setting on read()
import os   # needed only for demonstration
import sys  # needed only for demonstration
import nostalgic


class SettingsUI:

    def __init__(self):
        self.some_ui_thing_the_end_user_uses = 0


class Main:

    def __init__(self):
        self.cfg = nostalgic.Configuration("sample_config")
        self.settings_ui = SettingsUI()

        self.cfg.add_setting(
            "ui_related_thing",
            setter=self.custom_setter,  # called on read()
            getter=self.custom_getter)  # called on write()

    def custom_setter(self, value):
        print(f"Setting some_ui_thing_the_end_user_uses")
        self.settings_ui.some_ui_thing_the_end_user_uses = value

    def custom_getter(self):
        print(f"Getting some_ui_thing_the_end_user_uses")
        return self.settings_ui.some_ui_thing_the_end_user_uses


if __name__ == '__main__':
    main = Main()

    print(f"some_ui_thing_the_end_user_uses: "
          f"{main.settings_ui.some_ui_thing_the_end_user_uses}")  # 0, the initial value

    try:
        # second run
        main.cfg.read()
        print("Config just read")
        print(f"some_ui_thing_the_end_user_uses: "
              f"{main.settings_ui.some_ui_thing_the_end_user_uses}")
        os.remove(main.cfg.config_file)
        if not os.path.exists(main.cfg.config_file):
            print("Removed config file")
    except FileNotFoundError:
        # first run, no config yet

        # user changed the UI thing
        main.settings_ui.some_ui_thing_the_end_user_uses = 42
        main.cfg.write()
        print("Wrote config")
        sys.exit()

```

The first run gets the end-user value before writing:

```sh
$ python3 "/home/ahab/Projects/nostalgic/scratch/sample2.py"
some_ui_thing_the_end_user_uses: 0
Getting some_ui_thing_the_end_user_uses
Wrote config
```

The second run sets the end-user's previous value:

```sh
$ python3 "/home/ahab/Projects/nostalgic/scratch/sample2.py"
some_ui_thing_the_end_user_uses: 0
Setting some_ui_thing_the_end_user_uses
Config just read
some_ui_thing_the_end_user_uses: 42
Removed config file

```

Use the `sync` parameter of `read()` and `write()` to toggle whether
setters or getters are called.

Use `Configuration.set()` and `Configuration.get()` to apply or update
settings en masse without accessing the hard disk.

# Notes
- Shadowing Configuration methods with Settings of the same name is
  possible, although not recommended.  A warning will be given.

# Development
Install as "editable" using `pip`:

```sh
~$ cd Projects/nostalgic
~/Projects/nostalgic$ python3 -m venv venv
~/Projects/nostalgic$ source venv/bin/activate
(venv) ~/Projects/nostalgic$ pip install -e .
```

## Testing
Run tests using:

```sh
(venv) ~/Projects/nostalgic$ python3 tests/test_nostalgic.py
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://codeberg.org/excalamus/nostalgic",
    "name": "nostalgic",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": "",
    "keywords": "settings,configuration,configure,config,development,application",
    "author": "Matt Trzcinski",
    "author_email": "matt@excalamus.com",
    "download_url": "https://files.pythonhosted.org/packages/d8/46/8f28b4eb0db69d1ca9aa07b074ccf98beab1fc141f03c83a406139e9a9b1/nostalgic-1.4.1.tar.gz",
    "platform": null,
    "description": "> ***Savor what you feel and what you see / Things that may not seem important now / But may be tomorrow***\n>\n> *\u2013Chuck Schuldiner*\n\n# Nostalgic\nA drop-in configuration module to save and restore end-user and\napplication settings.\n\n- No meta-files\n- Built using only the Python standard library\n- Handle UI syncing\n\n# Install\n```python\npip install nostalgic\n```\n\n# Motivation\nMany configuration packages themselves require configuration files.\nThis often is extraneous.\n\nOthers provide a non-Pythonic API which hinders comprehension.  For\nexample, QSettings looks like\n\n```python\n# bad\nself.settings.setValue(\"my_tracked_variable\", value)\n```\n\nand\n\n```python\n# bad\nself.settings.value(\"my_tracked_variable\", DEFAULT_SETTINGS[\"my_tracked_variable\"])\n```\n\nHow you work with a variable depends on whether or not it's been\ntouched by Qt.\n\nWith Nostalgic, these calls look simply like\n\n```python\n# good\nself.settings.my_tracked_value = value\n```\n\nand\n\n```python\n# good\nself.settings.my_tracked_value\n```\n\nFurthermore, most applications likely require only a single\nconfiguration.  Nostalgic uses a Configuration singleton for this\nreason.  Instantiate a Configuration and the next time one is created,\nit will be a reference to the already extant Configuration.  This\nmeans explicit references to the Configuration don't need to be passed\naround.\n\n# Quick Start\nA Configuration is a collection of Settings.\n\n- Use a dot to get the Setting value (like an attribute)\n- Settings can have a default initial value\n- `write()` settings to disk and `read()` them back in\n\n```python\n# basic usage\nimport os   # needed only for demonstration\nimport sys  # needed only for demonstration\nimport nostalgic\n\n\nif __name__ == '__main__':\n    # create configuration in current directory\n    cfg = nostalgic.Configuration(\"sample_config\")\n\n    # declare a setting 'foo' with initial value\n    cfg.add_setting(\"foo\", default=\"bar\")\n\n    print(cfg.foo)  # \"bar\"\n\n    # change the value\n    cfg.foo = \"baz\"\n\n    try:\n        # second run\n        cfg.read()\n        print(\"Config just read\")\n        print(cfg.foo)  # \"baz\"\n        os.remove(cfg.config_file)\n        if not os.path.exists(cfg.config_file):\n            print(\"Removed config file\")\n    except FileNotFoundError:\n        # first run, no config yet\n        cfg.write()\n        print(\"Wrote config\")\n        sys.exit()\n\n```\n\n```sh\n$ python3 \"/home/ahab/Projects/nostalgic/scratch/sample1.py\"\nbar\nWrote config\n\n$ python3 \"/home/ahab/Projects/nostalgic/scratch/sample1.py\"\nbar\nConfig just read\nbaz\nRemoved config file\n```\n\n## Advanced: coordinate a configuration with the UI\nOptional setter and getter functions handle updating other parts of your code.\n\n```python\n# demonstrate getting on write() and setting on read()\nimport os   # needed only for demonstration\nimport sys  # needed only for demonstration\nimport nostalgic\n\n\nclass SettingsUI:\n\n    def __init__(self):\n        self.some_ui_thing_the_end_user_uses = 0\n\n\nclass Main:\n\n    def __init__(self):\n        self.cfg = nostalgic.Configuration(\"sample_config\")\n        self.settings_ui = SettingsUI()\n\n        self.cfg.add_setting(\n            \"ui_related_thing\",\n            setter=self.custom_setter,  # called on read()\n            getter=self.custom_getter)  # called on write()\n\n    def custom_setter(self, value):\n        print(f\"Setting some_ui_thing_the_end_user_uses\")\n        self.settings_ui.some_ui_thing_the_end_user_uses = value\n\n    def custom_getter(self):\n        print(f\"Getting some_ui_thing_the_end_user_uses\")\n        return self.settings_ui.some_ui_thing_the_end_user_uses\n\n\nif __name__ == '__main__':\n    main = Main()\n\n    print(f\"some_ui_thing_the_end_user_uses: \"\n          f\"{main.settings_ui.some_ui_thing_the_end_user_uses}\")  # 0, the initial value\n\n    try:\n        # second run\n        main.cfg.read()\n        print(\"Config just read\")\n        print(f\"some_ui_thing_the_end_user_uses: \"\n              f\"{main.settings_ui.some_ui_thing_the_end_user_uses}\")\n        os.remove(main.cfg.config_file)\n        if not os.path.exists(main.cfg.config_file):\n            print(\"Removed config file\")\n    except FileNotFoundError:\n        # first run, no config yet\n\n        # user changed the UI thing\n        main.settings_ui.some_ui_thing_the_end_user_uses = 42\n        main.cfg.write()\n        print(\"Wrote config\")\n        sys.exit()\n\n```\n\nThe first run gets the end-user value before writing:\n\n```sh\n$ python3 \"/home/ahab/Projects/nostalgic/scratch/sample2.py\"\nsome_ui_thing_the_end_user_uses: 0\nGetting some_ui_thing_the_end_user_uses\nWrote config\n```\n\nThe second run sets the end-user's previous value:\n\n```sh\n$ python3 \"/home/ahab/Projects/nostalgic/scratch/sample2.py\"\nsome_ui_thing_the_end_user_uses: 0\nSetting some_ui_thing_the_end_user_uses\nConfig just read\nsome_ui_thing_the_end_user_uses: 42\nRemoved config file\n\n```\n\nUse the `sync` parameter of `read()` and `write()` to toggle whether\nsetters or getters are called.\n\nUse `Configuration.set()` and `Configuration.get()` to apply or update\nsettings en masse without accessing the hard disk.\n\n# Notes\n- Shadowing Configuration methods with Settings of the same name is\n  possible, although not recommended.  A warning will be given.\n\n# Development\nInstall as \"editable\" using `pip`:\n\n```sh\n~$ cd Projects/nostalgic\n~/Projects/nostalgic$ python3 -m venv venv\n~/Projects/nostalgic$ source venv/bin/activate\n(venv) ~/Projects/nostalgic$ pip install -e .\n```\n\n## Testing\nRun tests using:\n\n```sh\n(venv) ~/Projects/nostalgic$ python3 tests/test_nostalgic.py\n```\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "A drop-in configuration module to save and restore end-user and application settings",
    "version": "1.4.1",
    "split_keywords": [
        "settings",
        "configuration",
        "configure",
        "config",
        "development",
        "application"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "31809a8ea41cdd40eb34f31f01ea82f5",
                "sha256": "e42e2ab6462c0b69c404bba81126f3f96fc82c36a95e3200df12e860dd3d8895"
            },
            "downloads": -1,
            "filename": "nostalgic-1.4.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "31809a8ea41cdd40eb34f31f01ea82f5",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 6967,
            "upload_time": "2022-06-21T00:41:24",
            "upload_time_iso_8601": "2022-06-21T00:41:24.700927Z",
            "url": "https://files.pythonhosted.org/packages/b2/c6/b7a514929d544533a49e89a298bbad11922328b13ca8bd557e9484272af5/nostalgic-1.4.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "md5": "c976d1d021c863222520b028dac3272d",
                "sha256": "8cb093dc27a949beb8b6671bf10ca5b8c991c140df1ae8fd948e0eaa9317eaf2"
            },
            "downloads": -1,
            "filename": "nostalgic-1.4.1.tar.gz",
            "has_sig": false,
            "md5_digest": "c976d1d021c863222520b028dac3272d",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 8531,
            "upload_time": "2022-06-21T00:41:26",
            "upload_time_iso_8601": "2022-06-21T00:41:26.378592Z",
            "url": "https://files.pythonhosted.org/packages/d8/46/8f28b4eb0db69d1ca9aa07b074ccf98beab1fc141f03c83a406139e9a9b1/nostalgic-1.4.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2022-06-21 00:41:26",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "lcname": "nostalgic"
}
        
Elapsed time: 0.44685s