freewso / autokey

Automatically exported from code.google.com/p/autokey
GNU General Public License v3.0
0 stars 0 forks source link

Feature request: global persistent variables #189

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
I would like to have variables that can be used across scripts. I have made a 
class that does this with variables stored on disk, and suggest that it be 
incorporated in the lib.scripting.Store class.

#-------------------------------------------------------------------------------
------
# global_vars.py

import json
from autokey import common

'''
SAMPLE USE CASE:

You want to write equations for both websites and in latex. 

When in websites, you want to use formulas delimiers such as <eq>x^2</eq> 

When in latex, you want \[ x^2\].

Also you will be using the same editor for both (Eclipse for example), so using 
window class is not an option.

In order to do this, we want a global switch which says if we are in websites 
mode or not. You could want to type for example

'eq;'

and qet

<eq></eq>

then toogle the switch with something like

'tws/'

for Toogle Web Switch, and the next time you type

'eq;'

you will get 

\[\]

magic! Of course, doing 'tws/' will go back to you web mode.

PROBLEM:

The only problem is that you need to access and modify the switch variable 
across scripts, which is not currently natively supported as of 0.82.2. 

SOLUTION:

This is exactly what this class does by saving a json to 
$/.config/autokey/dateya/global_vars.json , just next to the other data files 
used by autok.

PERFORMANCE:

Remember that all of the variables are written/read to/from disk which is an 
expensive step, so if you are going to make a huge number of variable 
read/writes in a script, it is better to write/get the variables all at once 
with a single set_globals()/get_globals() call, which will access disk only 
once.

INITIALIZATION:

Before you use the switch the first time, you must first use a command to 
initialize the data, which simply creates/overwrites the json on your disk. 

If you don't initialize for the first time you will get an script error because 
the json does not yet exit.

Put all of your initializations in a default init file, so that you will be 
able to restore all of your variables at once, either to return to default or 
if you accidentally erase them.

After the first time you initialize you don't need to do it anymore unless you 
want to go  back to the initial state. If don't reinitialize, you just return 
to your last session settings, which might be desirable.

INSTALLATION:

- put this file (global_vars.py) in your modules folder (Edit > Preferences > 
Script Engine)

USAGE EXAMPLES: (3 inner scripts, added in the GUI and set shortcuts to them):

- initialize global variables as in init_global_vars.py script
- send context sensitive expansions as in send_key_switch_sensitive.py script
- toogle the switch as in the toogle_switch script.py

#-------------------------------------------------------------------------------
# init_global.py (inner script)

# This script initializes the global variable switch. It must be call

from global_vars import GlobalVars

gvars =  { 'web_switch':True,  'web_switch_true':'<eq></eq>', 
'web_switch_false':r'\[\]',} 

GlobalVars.set_globals(gvars)

#-------------------------------------------------------------------------------
# send_key_switch_sensitive.py (inner script)

from global_vars import GlobalVars

gvars = GlobalVars.get_globals()

if( gvars['web_switch']  ):
    keyboard.send_keys( gvars['web_switch_true'] )
else:
    keyboard.send_keys( gvars['web_switch_false'] )

#-------------------------------------------------------------------------------
# toogle_switch.py (inner script)

from global_vars import GlobalVars

if(  GlobalVars.get_global('web_switch')  ):
    GlobalVars.set_global('web_switch', False)
else:
    GlobalVars.set_global('web_switch',True)

'''
class GlobalVars:

    global_vars_json_path = common.CONFIG_DIR + '/data/global_vars.json'

    '''Erases all the globals. This may be useful if you feel that the json is getting too cluttered with old unused variables. You must reinitialize variables before you use them again.'''
    @staticmethod
    def remove_all_globals():
        GlobalVars.set_all_globals_to({})

    '''Erases all globals, and then creates the variables given in the name/value pairs dictionary gvars.'''
    @staticmethod
    def set_all_globals_to(gvars):  

        json_string = json.dumps(gvars)

        f  = open(GlobalVars.global_vars_json_path, 'w')
        f.write(json_string)
        f.close()

    '''Sets/creates a global variable with a name name to the value value.'''
    @staticmethod
    def set_global(name,value):

        gvars = GlobalVars.get_globals()
        gvars[name] = value
        GlobalVars.set_all_globals_to(gvars)

    '''Sets/creates the values of each variable name in the given dictionary of name/value pairs gvars.'''
    @staticmethod        
    def set_globals(gvars):

        all_gvars = GlobalVars.get_globals()

        for name in gvars.keys():
            all_gvars[name] = gvars[name]

        GlobalVars.set_all_globals_to(all_gvars)

    '''Returns the value of the global variable with name name. Gives an error if it doesn't exist.'''
    @staticmethod
    def get_global(name):
        return GlobalVars.get_globals()[name]

    '''Returns the dictionary of all name/value pairs of global variables.'''
    @staticmethod
    def get_globals():

        f  = open(GlobalVars.global_vars_json_path, 'r')
        json_string = f.read()
        f.close()

        return json.loads(json_string)

#test main
if __name__ == '__main__':

    print "Testing global_vars.py\n"

    gvars1 = {'name11':'val11','name12':'val12','name13':'val13',}
    gvars2 = {'name21':'val21'}

    print '\njson path:\n' + GlobalVars.global_vars_json_path

    # remove_all_globals
    GlobalVars.remove_all_globals()

    # set_all_globals_to and get_globals
    GlobalVars.set_all_globals_to(gvars1)
    print GlobalVars.get_globals()
    GlobalVars.set_all_globals_to(gvars2)
    print GlobalVars.get_globals()

    # set_global
    GlobalVars.set_all_globals_to(gvars1)
    GlobalVars.set_global('name11','new_val11')
    GlobalVars.set_global('new_name','new_val')
    print GlobalVars.get_globals()

    # set_globals
    GlobalVars.set_all_globals_to(gvars2)
    GlobalVars.set_globals(gvars1)
    print GlobalVars.get_globals()

    # get_global
    GlobalVars.set_all_globals_to(gvars1)
    print GlobalVars.get_global('name11')
    #error!
    #GlobalVars.get_global('unexistent_var')

    GlobalVars.remove_all_globals()

Original issue reported on code.google.com by ciro.san...@gmail.com on 23 Mar 2012 at 11:42

GoogleCodeExporter commented 8 years ago

Original comment by cdekter on 2 Apr 2012 at 3:09

GoogleCodeExporter commented 8 years ago
Thanks for your contribution. I've come up with my own interpretation of your 
idea that will integrate better with the scripting API. Are you willing to do 
some testing? You would need to be running a distro with Gnome3 
available/installed.

Original comment by cdekter on 20 Apr 2012 at 10:09

GoogleCodeExporter commented 8 years ago
Implemented for next release

Original comment by cdekter on 20 Apr 2012 at 11:33

GoogleCodeExporter commented 8 years ago
That's great!

I'd like to test it, I'm on Ubuntu 11.10 and running Gnome 3 instead of Unity, 
just need installation instructions.

Another related thing that's on my mind, would it be possible to run all the 
commands from a single hidden python instance/terminal that runs all the time 
on the background of Autokey, so that one could just define variables as 

"a=1" inside scriptA.py

and use it in

scriptB.py?

without  writting to disk? 

If this were easy to implement, it would be in my opinion the preferred way of 
doing things when persistence between sessions is not necessary

Original comment by ciro.san...@gmail.com on 20 Apr 2012 at 11:49

GoogleCodeExporter commented 8 years ago
Ok tried it and it works.

Original comment by ciro.san...@gmail.com on 1 May 2012 at 12:37