-
Notifications
You must be signed in to change notification settings - Fork 0
Config
While this isn't the biggest class, or most important, it's one you'll probably get to dig into as you add more features and want saveable options. It's kinda like a poor man's homebrew GConf, but it works cross-platform, which is the whole reason we didn't go with GConf in the first place.
There is one global config file per user account on a system, in the ~/.pytide folder. This is a hidden folder in the home directory on Mac and Linux, and an obnoxiously-named folder in your personal user directory on Windows (we'll fix that later, maybe, but it may or may not be worth the effort to work with Windows' proprietary and "creative" methods of marking a folder as hidden). This is your home PyTide folder, the place where all persistence classes load and save their data. The home of the cache, and such. If you see this paragraph copied and pasted into the documentation of every persistence class, it's only because it applies to all of them.
In the persistence folder is, among other things, a lonely little file called "config". It has no extension, nor does it need one. It holds all the config information necessary to run PyTide, including saved passwords and preferences. The file is in JSON, which makes the saved passwords a bit vulnerable (if someone who knows security could fix that, that would be a really really good thing to do). But for most stuff, it does the job fine. At the top level, it's basically a dict that contains a number of "namespaces," each of which is also a dict. A config object can only access one namespace at a time, and for simplicity's sake, we encourage you to not use one config to access different namespaces at different times. I mean, you can, it's definitely built right into the code and it's stable, but it's also kind of a bad coding practice and will probably cause you headaches in the future.
When you create a Config object, you usually want to pass it a namespace in the constructor and not change the namespace after that. Doing so will automatically load current preferences from that namespace at initialization time. However, because of the threaded nature of Configs, you can't assume it will immediately be loaded right after you call the constructor. That's what the onload variable is for, providing a callback function for immediately after loading from the hard drive. You can also pass data to the constructor to immediately set into the Config's datawith the "data" variable (dicts only), for example, in case there is no namespace in the disk copy by that name (which by default creates a blank one), but remember that data loaded from disk will override this "default" data.
If you want to use autosaving instead of manual saving, the easiest way is to put it into the constructor. Remember, the constructor is your friend in this class - it's almost always the easiest way to do anything, even though lots of manual functions are available too. Simply set autosave to the number of seconds delay between a change to the Config's data and a write event. This allows changes to collect and be written to disk in one shot.
I'm going to assume you went with the easy route and did all the saving and loading setup in the constructor (if not, the functions aren't too badly documented in the code itself), and I'm going to go over the functions you're going to use on a daily basis (skip to the getAll() function if you want to jump straight to the good stuff).
Takes a dict, which it merges into the current internal data, and starts the autosave timer. Please, do not ever use the internal function _set(), or bad things will happen. If you can provide me with a good reason, a note from your doctor, and written permission from the Attorney General of the United States, I may consider allowing its usage. But just... don't.
Where "name" is the name of a key. Returns the value associated with that key. Can be any default type in Python, like a list or a dict, but since this all gets saved down to JSON and back, don't use any custom classes.
Test whether a key has been set in a Config. We prefer this to try/except because try/except tends to crash the internal thready stuff and hang the program. Hehe yeah checking before you get() is kinda important
Don't really feel like going through all the pain and agony of these functions? Try using getAll() to pull out a full copy of the whole namespace in dict form, which you can mess with on your own time to your heart's content, and then merge back in with the set() function! In many cases, this is more efficient, not least because of all the thread-safety code that has to run every time you call a function of a Config object.
Back to How the Code Works