Esempio n. 1
0
Otherwise you will need to install LinuxCNC 2.8, info on how
to do that can be found here: https://gnipsel.com/linuxcnc/uspace/
""".strip()

INSTALLED_ERROR_MSG = """
\033[31mERROR:\033[0m Can not edit an installed VCP

The specified VCP appears to be installed in the `python2.7/site-packages` 
directory. Please set up a development install to edit the VCP.
""".strip()

if linuxcnc.version.startswith('2.7'):
    print LCNC_VERSION_ERROR_MSG.format(linuxcnc.version)
    sys.exit(1)

LOG = initBaseLogger('qtpyvcp', log_file=os.devnull, log_level='WARNING')


def launch_designer(opts=DotDict()):

    if not opts.vcp and not opts.ui_file:
        fname, _ = QFileDialog.getOpenFileName(
            parent=None,
            caption="Choose VCP to Edit in QtDesigner",
            filter=
            "VCP Config Files (*.yml *.yaml);;VCP UI Files (*.ui);;All Files (*)",
            options=QFileDialog.Options() | QFileDialog.DontUseNativeDialog)

        if not fname:
            sys.exit(1)
Esempio n. 2
0
    sys.exit()

import qtpy
if qtpy.API != 'pyqt5':
    print(
        "ERROR: You must use the PyQt5 bindings in order to use the custom \n"
        "widgets in QtDesigner.")
    sys.exit()

os.environ['DESIGNER'] = 'true'

from qtpyvcp.utilities.logger import initBaseLogger

LOG = initBaseLogger("qtpyvcp-designer",
                     log_level=os.getenv('QTPYVCP_LOG_LEVEL', 'ERROR'),
                     log_file=os.getenv(
                         'QTPYVCP_LOG_FILE',
                         os.path.expanduser('~/qtpyvcp-designer.log')))

from qtpyvcp import CONFIG, DEFAULT_CONFIG_FILE
os.environ['VCP_CONFIG_FILES'] = os.getenv('VCP_CONFIG_FILES', '') + \
                                 ':' + DEFAULT_CONFIG_FILE

from qtpyvcp.utilities.config_loader import load_config_files_from_env

CONFIG.update(load_config_files_from_env())

from qtpyvcp.app.launcher import loadPlugins

loadPlugins(CONFIG['data_plugins'])
Esempio n. 3
0
from qtpy import API
from qtpy.QtCore import QTimer, Slot, Qt
from qtpy.QtWidgets import QApplication, QStyleFactory

import qtpyvcp

from qtpyvcp.utilities.logger import initBaseLogger
from qtpyvcp.plugins import getPlugin
from qtpyvcp.widgets.base_widgets.base_widget import QtPyVCPBaseWidget
from qtpyvcp.widgets.form_widgets.main_window import VCPMainWindow

# initialize logging. If a base logger was already initialized in a startup
# script (e.g. vcp_launcher.py), then that logger will be returned, otherwise
# this will initialise a base logger with default log level of DEBUG
LOG = initBaseLogger('qtpyvcp')

# Needed to silence this PySide2 warning:
#    Qt WebEngine seems to be initialized from a plugin. Please set
#    Qt::AA_ShareOpenGLContexts using QCoreApplication::setAttribute
#    before constructing QGuiApplication.
if API == 'pyside2':
    from qtpy.QtCore import Qt
    QApplication.setAttribute(Qt.AA_ShareOpenGLContexts)


class VCPApplication(QApplication):
    def __init__(self, theme=None, stylesheet=None):
        app_args = (qtpyvcp.OPTIONS.command_line_args or "").split()
        super(VCPApplication, self).__init__(app_args)
Esempio n. 4
0
# pydevd.settrace()

from io import TextIOWrapper

from subprocess import Popen, PIPE, STDOUT
from pkg_resources import iter_entry_points

from docopt import docopt
from qtpy.QtWidgets import QApplication, QFileDialog

from qtpyvcp.lib.types import DotDict
from qtpyvcp.utilities.logger import initBaseLogger

from linuxcnc import version as lcnc_version

LOG = initBaseLogger('EditVCP', log_file=None, log_level='DEBUG')

DESIGNER_LOG = initBaseLogger('Designer', log_file=None, log_level='DEBUG')

LCNC_VERSION_ERROR_MSG = """
\033[31mERROR:\033[0m Unsupported LinuxCNC version

QtPyVCP only supports LinuxCNC 2.8, current version is {}.
If you have LinuxCNC installed as a RIP make sure you have
activated the run-in-place environment by running:\n"

    $ . <linuxcnc-rip-dir>/scripts/rip-environment

Otherwise you will need to install LinuxCNC 2.8, info on how
to do that can be found here: https://gnipsel.com/linuxcnc/uspace/
""".strip()
Esempio n. 5
0
def parse_opts(doc=__doc__,
               vcp_name='NotSpecified',
               vcp_cmd='notspecified',
               vcp_version=None):
    # LinuxCNC passes the INI file as `-ini=inifile` which docopt sees as a
    # short argument which does not support an equals sign, so we loop thru
    # and add another dash to the ini argument if needed.
    for index, item in enumerate(sys.argv):
        if item.startswith('-ini'):
            sys.argv[index] = '-' + item
            break

    version_str = 'QtPyVCP {}'.format(QTPYVCP_VERSION)
    if vcp_version is not None:
        version_str += ', {} v{}'.format(vcp_name, vcp_version)

    doc = doc.format(vcp_name=vcp_name, vcp_cmd=vcp_cmd)

    raw_args = docopt(doc, version=version_str)

    def convType(val):
        if isinstance(val, basestring):
            if val.lower() in ['true', 'on', 'yes', 'false', 'off', 'no']:
                return val.lower() in ['true', 'on', 'yes']

            try:
                return int(val)
            except ValueError:
                pass

            try:
                return float(val)
            except ValueError:
                pass

        return val

    # convert raw argument dict keys to valid python attribute names
    opts = DotDict({
        arg.strip('-<>').replace('-', '_'): convType(value)
        for arg, value in raw_args.items()
    })

    # read options from INI file and merge with cmd line options
    ini_file = ini(
        normalizePath(opts.ini, os.path.expanduser('~/linuxcnc/configs')))
    for k, v in opts.iteritems():
        ini_val = ini_file.find('DISPLAY', k.upper().replace('-', '_'))
        if ini_val is None:
            continue

        # convert str values to bool
        if type(v) == bool:
            # TODO: Find a way to prefer cmd line values over INI values
            ini_val = ini_val.lower() in ['true', 'on', 'yes', '1']

        # if its a non bool value and it was specified on the cmd line
        # then prefer the cmd line value
        elif v is not None:
            continue

        opts[k] = convType(ini_val)

    # Check if LinuxCNC is running
    if not os.path.isfile('/tmp/linuxcnc.lock'):
        # LinuxCNC is not running.
        # TODO: maybe launch LinuxCNC using subprocess?
        print 'LinuxCNC must be running to launch a VCP'
        sys.exit()

    # setup the environment variables
    ini_file = os.environ.get('INI_FILE_NAME') or opts.ini
    if ini_file is None:
        print 'LinuxCNC is running, but you must specify the INI file'
        sys.exit()

    if not os.getenv('INI_FILE_NAME'):
        base_path = os.path.expanduser('~/linuxcnc/configs')
        ini_file = os.path.realpath(normalizePath(ini_file, base_path))
        if not os.path.isfile(ini_file):
            print 'Specified INI file does not exist: {}'.format(ini_file)
            sys.exit()
        os.environ['INI_FILE_NAME'] = ini_file
        os.environ['CONFIG_DIR'] = os.path.dirname(ini_file)

    if opts.qt_api:
        os.environ['QT_API'] = opts.qt_api

    if opts.config_file is not None:
        # cmd line config file should be relative to INI file
        config_dir = os.getenv('CONFIG_DIR', '')
        config_file_path = normalizePath(opts.config_file, config_dir)
        if not os.path.isfile(config_file_path):
            print 'Specified YAML file does not exist: {}'.format(
                config_file_path)
            sys.exit()
        opts.config_file = config_file_path

    # show the chooser if the --chooser flag was specified
    if opts.chooser or not opts.get('vcp', True):
        from qtpyvcp.vcp_chooser import VCPChooser
        from qtpy.QtWidgets import QApplication, qApp
        app = QApplication([])
        result = VCPChooser(opts).exec_()
        if result == VCPChooser.Rejected:
            sys.exit()

        # destroy the evidence
        qApp.deleteLater()
        del app

    # normalize log file path
    log_file = normalizePath(opts.log_file,
                             os.getenv('CONFIG_DIR') or os.getenv('HOME'))

    if log_file is None or os.path.isdir(log_file):
        log_file = os.path.expanduser('~/qtpyvcp.log')

    opts.log_file = log_file

    # init the logger
    from qtpyvcp.utilities import logger
    LOG = logger.initBaseLogger('qtpyvcp',
                                log_file=opts.log_file,
                                log_level=opts.log_level or "INFO")

    LOG.info("QtPyVCP Version: %s", QTPYVCP_VERSION)

    if LOG.getEffectiveLevel() == logger.LOG_LEVEL_MAPPING['DEBUG']:
        import qtpy
        LOG.debug("Qt Version: %s", qtpy.QT_VERSION)
        LOG.debug("Qt API: %s", qtpy.QT_API)
        LOG.debug("QtPy Version: %s", qtpy.__version__)

        LOG.debug("Command line options:\n%s",
                  json.dumps(opts, sort_keys=True, indent=4))

    return opts
Esempio n. 6
0
def apply_opts(opts):

    # read options from INI file and merge with cmd line options
    ini_file = normalizePath(opts.ini, os.path.expanduser('~/linuxcnc/configs'))
    ini_obj = ini(ini_file)
    for k, v in opts.iteritems():
        ini_val = ini_obj.find('DISPLAY', k.upper().replace('-', '_'))
        if ini_val is None:
            continue

        # convert str values to bool
        if type(v) == bool:
            # TODO: Find a way to prefer cmd line values over INI values
            ini_val = ini_val.lower() in ['true', 'on', 'yes', '1']

        # if its a non bool value and it was specified on the cmd line
        # then prefer the cmd line value
        elif v is not None:
            continue

        # If a VCP is specified in the INI as a .ui or .yaml file the path
        # should be relative to the config dir rather then the $PWD.
        if k.lower() == 'vcp' and ini_val.lower().split('.')[-1] in ['ui', 'yml', 'yaml']:
            ini_val = normalizePath(ini_val, os.path.dirname(ini_file))

        opts[k] = convType(ini_val)

    # Check if LinuxCNC is running
    if not os.path.isfile('/tmp/linuxcnc.lock'):
        # LinuxCNC is not running.
        # TODO: maybe launch LinuxCNC using subprocess?
        print 'LinuxCNC must be running to launch a VCP'
        sys.exit()

    # setup the environment variables
    ini_file = os.environ.get('INI_FILE_NAME') or opts.ini
    if ini_file is None:
        print 'LinuxCNC is running, but you must specify the INI file'
        sys.exit()

    if not os.getenv('INI_FILE_NAME'):
        base_path = os.path.expanduser('~/linuxcnc/configs')
        ini_file = os.path.realpath(normalizePath(ini_file, base_path))
        if not os.path.isfile(ini_file):
            print 'Specified INI file does not exist: {}'.format(ini_file)
            sys.exit()
        os.environ['INI_FILE_NAME'] = ini_file
        os.environ['CONFIG_DIR'] = os.path.dirname(ini_file)

    if opts.qt_api:
        os.environ['QT_API'] = opts.qt_api

    if opts.config_file is not None:
        # cmd line config file should be relative to INI file
        config_dir = os.getenv('CONFIG_DIR', '')
        config_file_path = normalizePath(opts.config_file, config_dir)
        if not os.path.isfile(config_file_path):
            print 'Specified YAML file does not exist: {}'.format(config_file_path)
            sys.exit()
        opts.config_file = config_file_path

    # show the chooser if the --chooser flag was specified
    if opts.chooser or not opts.get('vcp', True):
        from qtpyvcp.vcp_chooser import VCPChooser
        from qtpy.QtWidgets import QApplication, qApp
        app = QApplication([])
        result = VCPChooser(opts).exec_()
        if result == VCPChooser.Rejected:
            sys.exit()

        # destroy the evidence
        qApp.deleteLater()
        del app

    # normalize log file path
    log_file = normalizePath(opts.log_file,
                             os.getenv('CONFIG_DIR') or
                             os.getenv('HOME'))

    if log_file is None or os.path.isdir(log_file):
        log_file = os.path.expanduser('~/qtpyvcp.log')

    opts.log_file = log_file

    # init the logger
    from qtpyvcp.utilities import logger
    LOG = logger.initBaseLogger('qtpyvcp',
                                log_file=opts.log_file,
                                log_level=opts.log_level or "INFO")

    LOG.info("QtPyVCP Version: %s", QTPYVCP_VERSION)

    if LOG.getEffectiveLevel() == logger.logLevelFromName("DEBUG"):
        import qtpy
        LOG.debug("Qt Version: %s", qtpy.QT_VERSION)
        LOG.debug("Qt API: %s", qtpy.QT_API)
        LOG.debug("QtPy Version: %s", qtpy.__version__)


        LOG.debug("Command line options:\n%s",
                  json.dumps(opts, sort_keys=True, indent=4))

    return opts