You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ORPA-pyOpenRPA/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/idlexlib/extensionManager.py

272 lines
9.3 KiB

6 years ago
## """
## Copyright(C) 2011-2012 The Board of Trustees of the University of Illinois.
## All rights reserved.
##
## Developed by: Roger D. Serwy
## University of Illinois
##
## Permission is hereby granted, free of charge, to any person obtaining
## a copy of this software and associated documentation files (the
## "Software"), to deal with the Software without restriction, including
## without limitation the rights to use, copy, modify, merge, publish,
## distribute, sublicense, and/or sell copies of the Software, and to
## permit persons to whom the Software is furnished to do so, subject to
## the following conditions:
##
## + Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimers.
## + Redistributions in binary form must reproduce the above copyright
## notice, this list of conditions and the following disclaimers in the
## documentation and/or other materials provided with the distribution.
## + Neither the names of Roger D. Serwy, the University of Illinois, nor
## the names of its contributors may be used to endorse or promote
## products derived from this Software without specific prior written
## permission.
##
## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
## OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
## IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
## ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
## CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
## THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
##
import sys
if sys.version < '3':
from StringIO import StringIO
from Tkinter import *
import tkFileDialog
import tkMessageBox
else:
from io import StringIO
from tkinter import *
import tkinter.filedialog as tkFileDialog
import tkinter.messagebox as tkMessageBox
import imp
try:
import importlib
HAS_IMPORTLIB = True
except ImportError:
HAS_IMPORTLIB = False
from idlelib.configHandler import idleConf, IdleConfParser
import os
def make_config_parser(cfg):
""" Stuff Configration String into a fake file and return an IDLE config parser """
fp = StringIO()
fp.write(cfg)
fp.write('\n')
fp.seek(0)
# parse the configuration from the fake file
confparse = IdleConfParser('')
try:
confparse.readfp(fp)
except BaseException as e:
print('\n Configuration Parse Error', e)
return None
return confparse
class ExtensionManager(object):
""" Manages extensions for IdleX
"""
def __init__(self, path):
head,tail = os.path.split(path)
self.extension_dir = head
self.IDLEX_EXTENSIONS = self.get_idlex_extensions(head)
IDLE_EXTENSIONS = [] # A list of default extensions in IDLE - those that come with the standard distribution
for i in idleConf.defaultCfg['extensions'].sections():
if i.endswith('_cfgBindings') or i.endswith('_bindings'):
continue
IDLE_EXTENSIONS.append(i)
self.IDLE_EXTENSIONS = IDLE_EXTENSIONS
def get_idlex_extensions(self, directory):
""" Get a list of user extensions from 'directory' """
contents = os.listdir(directory)
contents.sort()
contents = [x for x in contents if not x.startswith('_')]
user_extensions = []
for i in contents:
fullpath = os.path.join(directory, i)
if fullpath.endswith('.py') \
and os.path.isfile(fullpath):
try:
txt = open(fullpath, 'r').read(1000)
except IOError:
print(' IOError while loading extension: %r' % fullpath)
if '# IDLEX EXTENSION' in txt:
name = i[:-3] # truncate .py
user_extensions.append(name)
else:
print(' Not an IdleX extension: %r' % fullpath)
return user_extensions
def load_extension(self, name):
""" Imports an extension by name and returns a reference to the module.
Invalid modules return None.
"""
fullname = 'extensions.%s' % name
try:
if HAS_IMPORTLIB:
mod = importlib.import_module('.' + fullname, package=__package__)
else:
mod = __import__(fullname, globals(), locals(), [''], 1)
except Exception as err:
import traceback
traceback.print_exc()
mod = None
return mod
def find_extension(self, name):
""" Locates an extension """
path = self.extension_dir
info = imp.find_module(name, [path])
def load_extension_cfg(self, extName):
""" Load the extension. get its default config string
from the "config_extension_def" variable."""
mod = self.load_extension(extName)
if mod is None:
print("could not load %s" % extName)
return
if hasattr(mod, "config_extension_def"):
return mod.config_extension_def
else:
print("\n Missing 'config_extension_def' in %s. Not loading." % extName)
return None
def copy_options(self, name, cfgdict, confparse, blank=False):
d = cfgdict["extensions"]
optionlist = confparse.GetOptionList(name)
for option in optionlist:
try:
value = confparse.get(name, option, raw=True)
except BaseException as e:
print(' Error during extension settings copy:\n', e)
return False
if not d.has_section(name):
d.add_section(name)
if not blank:
d.set(name, option, value)
else:
d.set(name, option, '')
return True
def transfer_cfg(self, extName, confparse, keys=True):
""" Transfer the configuration from the extension
into IDLE's configuration. Returns True if successful. """
if confparse is None:
return False
# copy the user extension configuration in IDLE
retval = self.copy_options(extName, idleConf.userCfg, confparse)
if 0: # DEVELOPERS - this takes a long time to process
# Report Any keybinding conflicts the user extension may have
keyset = idleConf.GetCurrentKeySet()
name_cfg = extName+'_cfgBindings'
optionlist = confparse.GetOptionList(name_cfg)
for option in optionlist:
b = '<<%s>>' % option
value = confparse.get(name_cfg, option)
if value == '<Control-Key-l>': continue # WORKAROUND: skip clear window binding
for event, binding in list(keyset.items()):
if value in binding and event != b and value:
print('\n Warning: [%s] has an event binding conflict with' % name_cfg)
print(' ', event, value)
# idleConf.GetExtensionBindings pulls only from the default configuration.
# Must transfer bindings to defaultCfg dictionary instead.
if keys:
self.copy_options(extName+'_cfgBindings', idleConf.defaultCfg,
confparse)
return retval
def load_idlex_extensions(self, userExt=None):
""" Load extensions. Returns number of extensions loaded. """
if userExt is None:
userExt = self.IDLEX_EXTENSIONS
# get already-saved settings
d = idleConf.GetUserCfgDir()
usercfgfile = os.path.join(d, 'idlex-config-extensions.cfg')
if os.path.isfile(usercfgfile):
U = open(usercfgfile).read()
else:
U = ''
count = 0
userConfParser = make_config_parser(U)
key_isdefault = idleConf.GetOption('main','Keys','default', type="bool")
for extName in userExt:
if self.reload_cfg(extName):
count += 1
# transfer already-saved settings, otherwise IDLE forgets them
# when idleConf.SaveUserCfgFiles is called from within IDLE. Bug?
self.transfer_cfg(extName, userConfParser,
keys=not key_isdefault) # Overwrite defaults with user config
idleConf.SaveUserCfgFiles()
return count
def reload_cfg(self, extName):
# get the default configuration for the individual extension
cfg = self.load_extension_cfg(extName)
if cfg is None:
return False
# shove the conf string into a ConfigParse object
extConfParser = make_config_parser(cfg)
if extConfParser is None:
print('\n Unable to parse configuration for %s' % extName)
return False
# transfer the configuration to IDLE
if not self.transfer_cfg(extName, extConfParser, keys=True):
print('\n Unable to transfer configuration for %s' % extName)
return False
return True
try:
from . import extensions
except (ImportError, ValueError) as err:
import extensions
path = extensions.__file__
extensionManager = ExtensionManager(path)