[pytango] 56/98: Move ITango to a separate project
Sandor Bodo-Merle
sbodomerle-guest at moszumanska.debian.org
Thu Sep 28 19:17:44 UTC 2017
This is an automated email from the git hooks/post-receive script.
sbodomerle-guest pushed a commit to tag v9.2.0
in repository pytango.
commit 49f804b095315f2d44a0ba06cc8d071d086d0744
Author: Vincent Michel <vincent.michel at maxlab.lu.se>
Date: Mon Jun 27 17:19:16 2016 +0200
Move ITango to a separate project
ITango now lives in a separate repo: https://github.com/tango-cs/itango.
The git history for the itango related files have been preserved.
Squashed commit of the following:
commit 470ce51f69aff0b2ef96d3939eef48355719e921
Author: Vincent Michel <vincent.michel at maxlab.lu.se>
Date: Mon Jun 27 16:05:23 2016 +0200
Remove winpostinstall script
commit 8414ffeb93a96531d78b12a75524bffd02a754ab
Author: Vincent Michel <vincent.michel at maxlab.lu.se>
Date: Mon Jun 27 15:58:34 2016 +0200
Remove itango documentation resources
commit f783b62609d6051997414c10e4f88a893f723408
Author: Vincent Michel <vincent.michel at maxlab.lu.se>
Date: Mon Jun 27 15:43:32 2016 +0200
Update ITango documentation
commit 7f44db31892e209e9e525194eb7d415c5245a1b8
Author: Vincent Michel <vincent.michel at maxlab.lu.se>
Date: Wed Jun 22 15:52:36 2016 +0200
Update itango documentation
commit 478fb183eb3f60d240b7215ac856080d0e8a4ee0
Author: Vincent Michel <vincent.michel at maxlab.lu.se>
Date: Wed Jun 22 15:04:47 2016 +0200
Remove itango from setup
commit 83f0a295552192c92d4ce06153097b581da6f9ef
Author: Vincent Michel <vincent.michel at maxlab.lu.se>
Date: Wed Jun 22 15:03:35 2016 +0200
Remove itango sources
---
doc/_static/itango.ico | Bin 16446 -> 0 bytes
doc/_static/itango.png | Bin 15517 -> 0 bytes
doc/_static/itango01.png | Bin 66682 -> 0 bytes
doc/_static/itango02.png | Bin 55182 -> 0 bytes
doc/_static/itango03.png | Bin 17471 -> 0 bytes
doc/_static/itango04.png | Bin 87205 -> 0 bytes
doc/_static/itango05.png | Bin 2885381 -> 0 bytes
doc/_static/itango06.png | Bin 137259 -> 0 bytes
doc/itango.rst | 706 +----------
scripts/pytango_winpostinstall.py | 69 -
setup.py | 59 +-
src/boost/python/ipython/__init__.py | 77 --
src/boost/python/ipython/common.py | 66 -
src/boost/python/ipython/eventlogger.py | 85 --
src/boost/python/ipython/ipython_00_10/__init__.py | 15 -
.../python/ipython/ipython_00_10/ipy_install.py | 99 --
src/boost/python/ipython/ipython_00_10/ipy_qt.py | 373 ------
.../python/ipython/ipython_00_10/ipython_00_10.py | 969 --------------
src/boost/python/ipython/ipython_00_11/__init__.py | 18 -
.../python/ipython/ipython_00_11/ipy_install.py | 102 --
.../python/ipython/ipython_00_11/ipython_00_11.py | 1269 ------------------
src/boost/python/ipython/ipython_10_00/__init__.py | 18 -
.../python/ipython/ipython_10_00/ipy_install.py | 109 --
.../python/ipython/ipython_10_00/ipython_10_00.py | 1340 --------------------
.../python/ipython/resource/ITangoConsole.svg | 422 ------
src/boost/python/ipython/resource/database.png | Bin 13726 -> 0 bytes
src/boost/python/ipython/resource/device.png | Bin 65909 -> 0 bytes
src/boost/python/ipython/resource/motor.png | Bin 13299 -> 0 bytes
src/boost/python/ipython/resource/serial.png | Bin 6323 -> 0 bytes
src/boost/python/ipython/resource/starter.png | Bin 15763 -> 0 bytes
winsetup.py | 10 +-
31 files changed, 15 insertions(+), 5791 deletions(-)
diff --git a/doc/_static/itango.ico b/doc/_static/itango.ico
deleted file mode 100644
index eb8e2dc..0000000
Binary files a/doc/_static/itango.ico and /dev/null differ
diff --git a/doc/_static/itango.png b/doc/_static/itango.png
deleted file mode 100644
index b4cd925..0000000
Binary files a/doc/_static/itango.png and /dev/null differ
diff --git a/doc/_static/itango01.png b/doc/_static/itango01.png
deleted file mode 100644
index 0fff50e..0000000
Binary files a/doc/_static/itango01.png and /dev/null differ
diff --git a/doc/_static/itango02.png b/doc/_static/itango02.png
deleted file mode 100644
index d50c853..0000000
Binary files a/doc/_static/itango02.png and /dev/null differ
diff --git a/doc/_static/itango03.png b/doc/_static/itango03.png
deleted file mode 100644
index 5c6cf90..0000000
Binary files a/doc/_static/itango03.png and /dev/null differ
diff --git a/doc/_static/itango04.png b/doc/_static/itango04.png
deleted file mode 100644
index f8c7a5b..0000000
Binary files a/doc/_static/itango04.png and /dev/null differ
diff --git a/doc/_static/itango05.png b/doc/_static/itango05.png
deleted file mode 100644
index 8e8d7fb..0000000
Binary files a/doc/_static/itango05.png and /dev/null differ
diff --git a/doc/_static/itango06.png b/doc/_static/itango06.png
deleted file mode 100644
index 60d346d..0000000
Binary files a/doc/_static/itango06.png and /dev/null differ
diff --git a/doc/itango.rst b/doc/itango.rst
index 97931c1..0ccf71a 100644
--- a/doc/itango.rst
+++ b/doc/itango.rst
@@ -10,705 +10,11 @@ ITango
ITango is a PyTango CLI based on IPython_. It is designed to be used as an
IPython profile.
-ITango is available since PyTango 7.1.2
-
-You can start ITango by typing on the command line::
-
- $ itango
-
-or the equivalent::
-
- $ ipython --profile=tango
-
-and you should get something like this:
-
-.. image:: _static/itango00.png
- :align: center
- :width: 75%
-
-
-.. _itango-features:
-
-Features
---------
-
-ITango works like a normal python console, but it gives you in addition a nice
-set of features from IPython_ like:
-
- - proper (bash-like) command completion
- - automatic expansion of python variables, functions, types
- - command history (with up/down arrow keys, %hist command)
- - help system ( object? syntax, help(object))
- - persistently store your favorite variables
- - color modes
-
-(for a complete list checkout the `IPython web page <http://ipython.org/>`_)
-
-Plus an additional set o Tango_ specific features:
-
- - automatic import of Tango objects to the console namespace (:mod:`PyTango`
- module, :class:`~PyTango.DeviceProxy` (=Device),
- :class:`~PyTango.Database`, :class:`~PyTango.Group`
- and :class:`~PyTango.AttributeProxy` (=Attribute))
- - device name completion
- - attribute name completion
- - automatic tango object member completion
- - list tango devices, classes, servers
- - customized tango error message
- - tango error introspection
- - switch database
- - refresh database
- - list tango devices, classes
- - store favorite tango objects
- - store favorite tango devices
- - tango color modes
-
-Check the :ref:`itango-highlights` to see how to put these feature to good use
-:-)
-
-
-.. currentmodule:: PyTango
-
-.. _itango-highlights:
-
-Highlights
-----------
-
-Tab completion
-~~~~~~~~~~~~~~
-
-ITango exports many tango specific objects to the console namespace.
-These include:
-
- - the PyTango module itself
-
- .. sourcecode:: itango
-
- ITango [1]: PyTango
- Result [1]: <module 'PyTango' from ...>
-
- - The :class:`DeviceProxy` (=Device), :class:`AttributeProxy` (=Attribute),
- :class:`Database` and :class:`Group` classes
-
- .. sourcecode:: itango
-
- ITango [1]: De<tab>
- DeprecationWarning Device DeviceProxy
-
- ITango [2]: Device
- Result [2]: <class 'PyTango._PyTango.DeviceProxy'>
-
- ITango [3]: Device("sys/tg_test/1")
- Result [3]: DeviceProxy(sys/tg_test/1)
-
- ITango [4]: Datab<tab>
-
- ITango [4]: Database
-
- ITango [4]: Att<tab>
- Attribute AttributeError AttributeProxy
-
- - The Tango :class:`Database` object to which the itango session is
- currently connected
-
- .. sourcecode:: itango
-
- ITango [1]: db
- Result [1]: Database(homer, 10000)
-
-Device name completion
-~~~~~~~~~~~~~~~~~~~~~~
-
-ITango knows the complete list of device names (including alias) for the current
-tango database. This means that when you try to create a new Device, by pressing
-<tab> you can see a context sensitive list of devices.
-
-.. sourcecode:: itango
-
- ITango [1]: test = Device("<tab>
- Display all 3654 possibilities? (y or n) n
-
- ITango [1]: test = Device("sys<tab>
- sys/access_control/1 sys/database/2 sys/tautest/1 sys/tg_test/1
-
- ITango [2]: test = Device("sys/tg_test/1")
-
-Attribute name completion
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-ITango can inspect the list of attributes in case the device server for the device
-where the attribute resides is running.
-
-.. sourcecode:: itango
-
- ITango [1]: short_scalar = Attribute("sys<tab>
- sys/access_control/1/ sys/database/2/ sys/tautest/1/ sys/tg_test/1/
-
- ITango [1]: short_scalar = Attribute("sys/tg_test/1/<tab>
- sys/tg_test/1/State sys/tg_test/1/no_value
- sys/tg_test/1/Status sys/tg_test/1/short_image
- sys/tg_test/1/ampli sys/tg_test/1/short_image_ro
- sys/tg_test/1/boolean_image sys/tg_test/1/short_scalar
- sys/tg_test/1/boolean_image_ro sys/tg_test/1/short_scalar_ro
- sys/tg_test/1/boolean_scalar sys/tg_test/1/short_scalar_rww
- sys/tg_test/1/boolean_spectrum sys/tg_test/1/short_scalar_w
- sys/tg_test/1/boolean_spectrum_ro sys/tg_test/1/short_spectrum
- sys/tg_test/1/double_image sys/tg_test/1/short_spectrum_ro
- sys/tg_test/1/double_image_ro sys/tg_test/1/string_image
- sys/tg_test/1/double_scalar sys/tg_test/1/string_image_ro
- ...
-
- ITango [1]: short_scalar = Attribute("sys/tg_test/1/short_scalar")
-
- ITango [29]: print test.read()
- DeviceAttribute[
- data_format = PyTango._PyTango.AttrDataFormat.SCALAR
- dim_x = 1
- dim_y = 0
- has_failed = False
- is_empty = False
- name = 'short_scalar'
- nb_read = 1
- nb_written = 1
- quality = PyTango._PyTango.AttrQuality.ATTR_VALID
- r_dimension = AttributeDimension(dim_x = 1, dim_y = 0)
- time = TimeVal(tv_nsec = 0, tv_sec = 1279723723, tv_usec = 905598)
- type = PyTango._PyTango.CmdArgType.DevShort
- value = 47
- w_dim_x = 1
- w_dim_y = 0
- w_dimension = AttributeDimension(dim_x = 1, dim_y = 0)
- w_value = 0]
-
-Automatic tango object member completion
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When you create a new tango object, (ex.: a device), itango is able to find out
-dynamically which are the members of this device (including tango commands
-and attributes if the device is currently running)
-
-.. sourcecode:: itango
-
- ITango [1]: test = Device("sys/tg_test/1")
-
- ITango [2]: test.<tab>
- Display all 240 possibilities? (y or n)
- ...
- test.DevVoid test.get_access_control
- test.Init test.get_asynch_replies
- test.State test.get_attribute_config
- test.Status test.get_attribute_config_ex
- test.SwitchStates test.get_attribute_list
- ...
-
- ITango [2]: test.short_<tab>
- test.short_image test.short_scalar test.short_scalar_rww test.short_spectrum
- test.short_image_ro test.short_scalar_ro test.short_scalar_w test.short_spectrum_ro
-
- ITango [2]: test.short_scalar # old style: test.read_attribute("short_scalar").value
- Result [2]: 252
-
- ITango [3]: test.Dev<tab>
- test.DevBoolean test.DevUShort test.DevVarShortArray
- test.DevDouble test.DevVarCharArray test.DevVarStringArray
- test.DevFloat test.DevVarDoubleArray test.DevVarULongArray
- test.DevLong test.DevVarDoubleStringArray test.DevVarUShortArray
- test.DevShort test.DevVarFloatArray test.DevVoid
- test.DevString test.DevVarLongArray
- test.DevULong test.DevVarLongStringArray
-
- ITango [3]: test.DevDouble(56.433) # old style: test.command_inout("DevDouble").
- Result [3]: 56.433
-
-Tango classes as :class:`DeviceProxy`
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-ITango exports all known tango classes as python alias to :class:`DeviceProxy`.
-This way, if you want to create a device of class which you already know
-(say, Libera, for example) you can do:
-
-.. sourcecode:: itango
-
- ITango [1]: lib01 = Libera("BO01/DI/BPM-01")
-
-One great advantage is that the tango device name completion is sensitive to the
-type of device you want to create. This means that if you are in the middle of
-writting a device name and you press the <tab> key, only devices of the tango
-class 'Libera' will show up as possible completions.
-
-.. sourcecode:: itango
-
- ITango [1]: bpm1 = Libera("<tab>
- BO01/DI/BPM-01 BO01/DI/BPM-09 BO02/DI/BPM-06 BO03/DI/BPM-03 BO03/DI/BPM-11 BO04/DI/BPM-08
- BO01/DI/BPM-02 BO01/DI/BPM-10 BO02/DI/BPM-07 BO03/DI/BPM-04 BO04/DI/BPM-01 BO04/DI/BPM-09
- BO01/DI/BPM-03 BO01/DI/BPM-11 BO02/DI/BPM-08 BO03/DI/BPM-05 BO04/DI/BPM-02 BO04/DI/BPM-10
- BO01/DI/BPM-04 BO02/DI/BPM-01 BO02/DI/BPM-09 BO03/DI/BPM-06 BO04/DI/BPM-03 BO04/DI/BPM-11
- BO01/DI/BPM-05 BO02/DI/BPM-02 BO02/DI/BPM-10 BO03/DI/BPM-07 BO04/DI/BPM-04
- BO01/DI/BPM-06 BO02/DI/BPM-03 BO02/DI/BPM-11 BO03/DI/BPM-08 BO04/DI/BPM-05
- BO01/DI/BPM-07 BO02/DI/BPM-04 BO03/DI/BPM-01 BO03/DI/BPM-09 BO04/DI/BPM-06
- BO01/DI/BPM-08 BO02/DI/BPM-05 BO03/DI/BPM-02 BO03/DI/BPM-10 BO04/DI/BPM-07
-
- ITango [1]: bpm1 = Libera("BO01<tab>
- BO01/DI/BPM-01 BO01/DI/BPM-03 BO01/DI/BPM-05 BO01/DI/BPM-07 BO01/DI/BPM-09 BO01/DI/BPM-11
- BO01/DI/BPM-02 BO01/DI/BPM-04 BO01/DI/BPM-06 BO01/DI/BPM-08 BO01/DI/BPM-10
-
- ITango [1]: bpm1 = Libera("BO01/DI/BPM-01")
-
-Customized device representation
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When you use ipython >= 0.11 with a Qt console frontend::
-
- $ itango qtconsole
-
-typing a variable containing a tango device object followend by :kbd:`Enter`
-will present you with a customized representation of the object instead of the
-usual :func:`repr` :
-
- .. image:: _static/itango06.png
-
-You can customize the icon that itango displays for a specific device.
-The first thing to do is to copy the image file into
-:mod:`PyTango.ipython.resource` installation directory (if you don't have
-permissions to do so, copy the image into a directory of your choosing
-and make sure it is accessible from itango).
-
-If you want to use the image for all devices of a certain tango class, just
-add a new tango class property called *__icon*. You can do it with jive or, of
-course, with itango itself::
-
- db.put_class_property("Libera", dict(__icon="libera.png"))
-
- # if you placed your image in a directory different than PyTango.ipython.resource
- # then, instead you have to specify the absolute directory
-
- db.put_class_property("Libera", dict(__icon="/home/homer/.config/itango/libera.png"))
-
-If you need different images for different devices of the same class, you can
-specify an *__icon* property at the device level (which takes precedence over
-the class property value, if defined)::
-
- db.put_device_property("BO01/DI/BPM-01", dict(__icon="libera2.png"))
-
-
-
-List tango devices, classes, servers
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-ITango provides a set of magic functions (ipython lingo) that allow you to check
-for the list tango devices, classes and servers which are registered in the
-current database.
-
-.. sourcecode:: itango
-
- ITango [1]: lsdev
- Device Alias Server Class
- ---------------------------------------- ------------------------- ------------------------- --------------------
- expchan/BL99_Dummy0DCtrl/1 BL99_0D1 Pool/BL99 ZeroDExpChannel
- simulator/bl98/motor08 Simulator/BL98 SimuMotor
- expchan/BL99_Dummy0DCtrl/3 BL99_0D3 Pool/BL99 ZeroDExpChannel
- expchan/BL99_Dummy0DCtrl/2 BL99_0D2 Pool/BL99 ZeroDExpChannel
- expchan/BL99_Dummy0DCtrl/5 BL99_0D5 Pool/BL99 ZeroDExpChannel
- expchan/BL99_Dummy0DCtrl/4 BL99_0D4 Pool/BL99 ZeroDExpChannel
- expchan/BL99_Dummy0DCtrl/7 BL99_0D7 Pool/BL99 ZeroDExpChannel
- expchan/BL99_Dummy0DCtrl/6 BL99_0D6 Pool/BL99 ZeroDExpChannel
- simulator/bl98/motor01 Simulator/BL98 SimuMotor
- simulator/bl98/motor02 Simulator/BL98 SimuMotor
- simulator/bl98/motor03 Simulator/BL98 SimuMotor
- mg/BL99/_mg_macserv_26065_-1320158352 Pool/BL99 MotorGroup
- simulator/bl98/motor05 Simulator/BL98 SimuMotor
- simulator/bl98/motor06 Simulator/BL98 SimuMotor
- simulator/bl98/motor07 Simulator/BL98 SimuMotor
- simulator/BL98/motctrl01 Simulator/BL98 SimuMotorCtrl
- expchan/BL99_Simu0DCtrl1/1 BL99_0D8 Pool/BL99 ZeroDExpChannel
- expchan/BL99_UxTimerCtrl1/1 BL99_Timer Pool/BL99 CTExpChannel
- ...
-
- ITango [1]: lsdevclass
- SimuCoTiCtrl TangoAccessControl ZeroDExpChannel
- Door Motor DataBase
- MotorGroup IORegister SimuMotorCtrl
- TangoTest MacroServer TauTest
- SimuMotor SimuCounterEx MeasurementGroup
- Pool CTExpChannel
-
- ITango [1]: lsserv
- MacroServer/BL99 MacroServer/BL98 Pool/V2
- Pool/BL99 Pool/BL98 TangoTest/test
- Pool/tcoutinho Simulator/BL98
- TangoAccessControl/1 TauTest/tautest DataBaseds/2
- MacroServer/tcoutinho Simulator/BL99
-
-Customized tango error message and introspection
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-ITango intercepts tango exceptions that occur when you do tango operations
-(ex.: write an attribute with a value outside the allowed limits) and tries to
-display it in a summarized, user friendly way.
-If you need more detailed information about the last tango error, you can use
-the magic command 'tango_error'.
-
-.. sourcecode:: itango
-
- ITango [1]: test = Device("sys/tg_test/1")
-
- ITango [2]: test.no_value
- API_AttrValueNotSet : Read value for attribute no_value has not been updated
- For more detailed information type: tango_error
-
- ITango [3]: tango_error
- Last tango error:
- DevFailed[
- DevError[
- desc = 'Read value for attribute no_value has not been updated'
- origin = 'Device_3Impl::read_attributes_no_except'
- reason = 'API_AttrValueNotSet'
- severity = PyTango._PyTango.ErrSeverity.ERR]
- DevError[
- desc = 'Failed to read_attribute on device sys/tg_test/1, attribute no_value'
- origin = 'DeviceProxy::read_attribute()'
- reason = 'API_AttributeFailed'
- severity = PyTango._PyTango.ErrSeverity.ERR]]
-
-Switching database
-~~~~~~~~~~~~~~~~~~
-
-You can switch database simply by executing the 'switchdb <host> [<port>]' magic
-command.
-
-.. sourcecode:: itango
-
- ITango [1]: switchdb
-
- Must give new database name in format <host>[:<port>].
- <port> is optional. If not given it defaults to 10000.
-
- Examples:
- switchdb homer:10005
- switchdb homer 10005
- switchdb homer
-
- ITango [2]: db
- Database(homer, 10000)
-
- ITango [3]: switchdb bart # by default port is 10000
-
- ITango [4]: db
- Database(bart, 10000)
-
- ITango [5]: switchdb lisa 10005 # you can use spaces between host and port
-
- ITango [6]: db
- Database(lisa, 10005)
-
- ITango [7]: switchdb marge:10005 # or the traditional ':'
-
- ITango [8]: db
- Database(marge, 10005)
-
-Refreshing the database
-~~~~~~~~~~~~~~~~~~~~~~~
-
-When itango starts up or when the database is switched, a query is made to the
-tango Database device server which provides all necessary data. This
-data is stored locally in a itango cache which is used to provide all the nice
-features.
-If the Database server is changed in some way (ex: a new device server is registered),
-the local database cache is not consistent anymore with the tango database.
-Therefore, itango provides a magic command 'refreshdb' that allows you to reread
-all tango information from the database.
-
-.. sourcecode:: itango
-
- ITango [1]: refreshdb
-
-Storing your favorite tango objects for later usage
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. note::
- This feature is not available if you have installed IPython 0.11!
-
-Since version 7.1.2, :class:`DeviceProxy`, :class:`AttributeProxy` and
-:class:`Database` became pickable.
-This means that they can be used by the IPython_ 'store' magic command (type
-'store?' on the itango console to get information on how to use this command).
-You can, for example, assign your favorite devices in local python variables and
-then store these for the next time you startup IPython_ with itango profile.
-
-.. sourcecode:: itango
-
- ITango [1]: theta = Motor("BL99_M1") # notice how we used tango alias
-
- ITango [2]: store theta
- Stored 'theta' (DeviceProxy)
-
- ITango [3]: Ctrl+D
-
- (IPython session is closed and started again...)
-
- ITango [1]: store -r # in some versions of IPython you may need to do this ...
-
- ITango [1]: print theta
- DeviceProxy(motor/bl99/1)
-
-Adding itango to your own ipython profile
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Adding itango to the ipython default profile
-##################################################
-
-Let's assume that you find itango so useful that each time you start ipython, you want
-itango features to be loaded by default.
-The way to do this is by editing your default ipython configuration file:
-
-1. On IPython <= 0.10
-
- $HOME/.ipython/ipy_user_conf.py and add the lines 1 and 7.
-
- .. note::
- The code shown below is a small part of your $HOME/.ipython/ipy_user_conf.py.
- It is shown here only the relevant part for this example.
-
- .. sourcecode:: python
-
- import PyTango.ipython
-
- def main():
-
- # uncomment if you want to get ipython -p sh behaviour
- # without having to use command line switches
- # import ipy_profile_sh
- PyTango.ipython.init_ipython(ip, console=False)
-
-2. On IPython > 0.10
-
- First you have to check which is the configuration directory being used by
- IPython. For this, in an IPython console type:
-
- .. sourcecode:: itango
-
- ITango [1]: import IPython.utils.path
-
- ITango [2]: IPython.utils.path.get_ipython_dir()
- <IPYTHON_DIR>
-
- now edit <IPYTHON_DIR>/profile_default/ipython_config.py and add the
- following line at the end to add itango configuration::
-
- load_subconfig('ipython_config.py', profile='tango')
-
- Alternatively, you could also load itango as an IPython extension::
-
- config = get_config()
- i_shell_app = config.InteractiveShellApp
- extensions = getattr(i_shell_app, 'extensions', [])
- extensions.append('PyTango.ipython')
- i_shell_app.extensions = extensions
-
- for more information on how to configure IPython >= 0.11 please check the
- `IPython configuration <http://ipython.org/ipython-doc/dev/config/ipython.html#configuring-the-ipython-command-line-application>`_
-
-And now, every time you start ipython::
-
- ipython
-
-itango features will also be loaded.
-
-.. sourcecode:: ipython
-
- In [1]: db
- Out[1]: Database(homer, 10000)
-
-
-Adding itango to an existing customized profile
-####################################################
-
-.. note::
- This chapter has a pending update. The contents only apply to
- IPython <= 0.10.
-
-If you have been working with IPython_ before and have already defined a
-customized personal profile, you can extend your profile with itango features
-without breaking your existing options. The trick is to initialize itango extension
-with a parameter that tells itango to maintain the existing options (like colors,
-command line and initial banner).
-
-So, for example, let's say you have created a profile called nuclear, and therefore
-you have a file called $HOME/.ipython/ipy_profile_nuclear.py with the following
-contents:
-
-.. sourcecode:: python
-
- import os
- import IPython.ipapi
-
- def main():
- ip = IPython.ipapi.get()
-
- o = ip.options
- o.banner = "Springfield nuclear powerplant CLI\n\nWelcome Homer Simpson"
- o.colors = "Linux"
- o.prompt_in1 = "Mr. Burns owns you [\\#]: "
-
- main()
-
-In order to have itango features available to this profile you simply need to
-add two lines of code (lines 3 and 7):
-
-.. sourcecode:: python
-
- import os
- import IPython.ipapi
- import PyTango.ipython
-
- def main():
- ip = IPython.ipapi.get()
- PyTango.ipython.init_ipython(ip, console=False)
-
- o = ip.options
- o.banner = "Springfield nuclear powerplant CLI\n\nMr. Burns owns you!"
- o.colors = "Linux"
- o.prompt_in1 = "The Simpsons [\\#]: "
-
- main()
-
-This will load the itango features into your profile while preserving your
-profile's console options (like colors, command line and initial banner).
-
-Creating a profile that extends itango profile
-####################################################
-
-.. note::
- This chapter has a pending update. The contents only apply to
- IPython <= 0.10.
-
-It is also possible to create a profile that includes all itango features and at
-the same time adds new ones. Let's suppose that you want to create a customized
-profile called 'orbit' that automaticaly exports devices of class
-'Libera' for the booster accelerator (assuming you are working on a synchrotron
-like institute ;-).
-Here is the code for the $HOME/.ipython/ipy_profile_orbit.py:
-
-.. sourcecode:: python
-
- import os
- import IPython.ipapi
- import IPython.genutils
- import IPython.ColorANSI
- import PyTango.ipython
- import StringIO
-
- def magic_liberas(ip, p=''):
- """Lists all known Libera devices."""
- data = PyTango.ipython.get_device_map()
- s = StringIO.StringIO()
- cols = 30, 15, 20
- l = "%{0}s %{1}s %{2}s".format(*cols)
- print >>s, l % ("Device", "Alias", "Server")
- print >>s, l % (cols[0]*"-", cols[1]*"-", cols[2]*"-")
- for d, v in data.items():
- if v[2] != 'Libera': continue
- print >>s, l % (d, v[0], v[1])
- s.seek(0)
- IPython.genutils.page(s.read())
-
- def main():
- ip = IPython.ipapi.get()
-
- PyTango.ipython.init_ipython(ip)
-
- o = ip.options
-
- Colors = IPython.ColorANSI.TermColors
- c = dict(Colors.__dict__)
-
- o.banner += "\n{Brown}Welcome to Orbit analysis{Normal}\n".format(**c)
-
- o.prompt_in1 = "Orbit [\\#]: "
- o.colors = "BlueTango"
-
- ip.expose_magic("liberas", magic_liberas)
-
- db = ip.user_ns.get('db')
- dev_class_dict = PyTango.ipython.get_class_map()
-
- if not dev_class_dict.has_key("Libera"):
- return
-
- for libera in dev_class_dict['Libera']:
- domain, family, member = libera.split("/")
- var_name = domain + "_" + member
- var_name = var_name.replace("-","_")
- ip.to_user_ns( { var_name : PyTango.DeviceProxy(libera) } )
-
- main()
-
-Then start your CLI with::
-
- $ ipython --profile=orbit
-
-and you will have something like this
-
-.. image:: _static/itango02.png
-
-Advanced event monitoring
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. note::
- This chapter has a pending update. The contents only apply to
- IPython <= 0.10.
-
-With itango it is possible to monitor change events triggered by any tango
-attribute which has events enabled.
-
-To start monitoring the change events of an attribute:
-
-.. sourcecode:: itango
-
- ITango [1]: mon -a BL99_M1/Position
- 'BL99_M1/Position' is now being monitored. Type 'mon' to see all events
-
-To list all events that have been intercepted:
-
-.. sourcecode:: itango
-
- ITango [2]: mon
- ID Device Attribute Value Quality Time
- ---- ---------------- ------------ ---------------- ------------- ----------------
- 0 motor/bl99/1 state ON ATTR_VALID 17:11:08.026472
- 1 motor/bl99/1 position 190.0 ATTR_VALID 17:11:20.691112
- 2 motor/bl99/1 state MOVING ATTR_VALID 17:12:11.858985
- 3 motor/bl99/1 position 188.954072857 ATTR_CHANGING 17:12:11.987817
- 4 motor/bl99/1 position 186.045533882 ATTR_CHANGING 17:12:12.124448
- 5 motor/bl99/1 position 181.295838155 ATTR_CHANGING 17:12:12.260884
- 6 motor/bl99/1 position 174.55354729 ATTR_CHANGING 17:12:12.400036
- 7 motor/bl99/1 position 166.08870515 ATTR_CHANGING 17:12:12.536387
- 8 motor/bl99/1 position 155.77528943 ATTR_CHANGING 17:12:12.672846
- 9 motor/bl99/1 position 143.358230136 ATTR_CHANGING 17:12:12.811878
- 10 motor/bl99/1 position 131.476140017 ATTR_CHANGING 17:12:12.950391
- 11 motor/bl99/1 position 121.555421781 ATTR_CHANGING 17:12:13.087970
- 12 motor/bl99/1 position 113.457930987 ATTR_CHANGING 17:12:13.226531
- 13 motor/bl99/1 position 107.319423091 ATTR_CHANGING 17:12:13.363559
- 14 motor/bl99/1 position 102.928229946 ATTR_CHANGING 17:12:13.505102
- 15 motor/bl99/1 position 100.584726495 ATTR_CHANGING 17:12:13.640794
- 16 motor/bl99/1 position 100.0 ATTR_ALARM 17:12:13.738136
- 17 motor/bl99/1 state ALARM ATTR_VALID 17:12:13.743481
-
- ITango [3]: mon -l mot.* state
- ID Device Attribute Value Quality Time
- ---- ---------------- ------------ ---------------- ------------- ----------------
- 0 motor/bl99/1 state ON ATTR_VALID 17:11:08.026472
- 2 motor/bl99/1 state MOVING ATTR_VALID 17:12:11.858985
- 17 motor/bl99/1 state ALARM ATTR_VALID 17:12:13.743481
-
-To stop monitoring the attribute:
-
-.. sourcecode:: itango
-
- ITango [1]: mon -d BL99_M1/Position
- Stopped monitoring 'BL99_M1/Position'
-
-.. note::
- Type 'mon?' to see detailed information about this magic command
+ .. image:: _static/itango00.png
+ITango is available since PyTango 7.1.2 and has been moved to a separate
+project since PyTango 9.2.0:
+* `package and instructions on PyPI <http://pypi.python.org/pypi/itango>`_
+* `sources on GitHub <https://github.com/tango-cs/itango>`_
+* `documentation on pythonhosted <http://pythonhosted.org/itango>`_
diff --git a/scripts/pytango_winpostinstall.py b/scripts/pytango_winpostinstall.py
deleted file mode 100644
index 1599369..0000000
--- a/scripts/pytango_winpostinstall.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# ------------------------------------------------------------------------------
-# This file is part of PyTango (http://www.tinyurl.com/PyTango)
-#
-# Copyright 2006-2012 CELLS / ALBA Synchrotron, Bellaterra, Spain
-# Copyright 2013-2014 European Synchrotron Radiation Facility, Grenoble, France
-#
-# Distributed under the terms of the GNU Lesser General Public License,
-# either version 3 of the License, or (at your option) any later version.
-# See LICENSE.txt for more info.
-# ------------------------------------------------------------------------------
-
-import sys
-import os.path
-
-def install():
- import struct
- bits = 8 * struct.calcsize("P")
- is_64 = bits == 64
- pyver = "(Py {1}.{2} {0}bits)".format(bits, *sys.version_info[:2])
-
- itango_lnk = 'ITango {0}.lnk'.format(pyver)
- itango_qt_lnk = 'ITango Qt {0}.lnk'.format(pyver)
-
- python = os.path.join(sys.prefix, 'python.exe')
- pythonw = os.path.join(sys.prefix, 'pythonw.exe')
-
- desktop = get_special_folder_path("CSIDL_COMMON_DESKTOPDIRECTORY")
- tango_menu = os.path.join(get_special_folder_path("CSIDL_COMMON_PROGRAMS"), 'Tango')
- itango_args = os.path.join(sys.prefix, 'scripts', 'itango-script.py')
- itango_qt_args = os.path.join(sys.prefix, 'scripts', 'itango-qt-script.pyw')
- itango_icon = os.path.join(sys.prefix, 'scripts', 'itango.ico')
- itango_workdir = ''
-
- # create desktop shortcuts
- itango_desktop_shortcut = os.path.join(desktop, itango_lnk)
- create_shortcut(python, "ITango console", itango_desktop_shortcut,
- itango_args, itango_workdir, itango_icon, 0)
- file_created(itango_desktop_shortcut)
-
- itango_qt_desktop_shortcut = os.path.join(desktop, itango_qt_lnk)
- create_shortcut(pythonw, "ITango Qt console", itango_qt_desktop_shortcut,
- itango_qt_args, itango_workdir, itango_icon, 0)
- file_created(itango_qt_desktop_shortcut)
-
- # create tango menu shortcuts
- itango_menu_shortcut = os.path.join(tango_menu, itango_lnk)
- create_shortcut(python, "ITango console", itango_menu_shortcut,
- itango_args, itango_workdir, itango_icon, 0)
- file_created(itango_menu_shortcut)
-
- itango_qt_menu_shortcut = os.path.join(tango_menu, itango_qt_lnk)
- create_shortcut(pythonw, "ITango Qt console", itango_qt_menu_shortcut,
- itango_qt_args, itango_workdir, itango_icon, 0)
- file_created(itango_qt_menu_shortcut)
-
-
-def remove():
- print ("Removing...")
- print ("DONE!")
-
-
-def main():
- if '-install' in sys.argv:
- return install()
- elif '-remove' in sys.argv:
- return remove()
-
-
-main()
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 160b447..8c850ec 100644
--- a/setup.py
+++ b/setup.py
@@ -28,26 +28,12 @@ from distutils.version import StrictVersion as V
try:
import sphinx
import sphinx.util.console
- sphinx.util.console.color_terminal = lambda : False
+ sphinx.util.console.color_terminal = lambda: False
from sphinx.setup_command import BuildDoc
except ImportError:
sphinx = None
try:
- import IPython
-except ImportError:
- IPython = None
-else:
- try:
- from IPython.paths import get_ipython_dir
- except ImportError:
- try:
- from IPython.utils.path import get_ipython_dir
- except ImportError:
- from IPython.genutils import get_ipython_dir
- _IPY_LOCAL = str(get_ipython_dir())
-
-try:
import numpy
except ImportError:
numpy = None
@@ -122,21 +108,8 @@ def has_numpy(with_src=True):
return ret
-def get_script_files():
- if os.name == "nt":
- return ["scripts/pytango_winpostinstall.py"]
- return []
-
-
-def get_entry_points():
- major = int(platform.python_version_tuple()[0])
- itango = 'itango3' if major == 3 else 'itango'
- return {
- "console_scripts": ["{0} = PyTango.ipython:run".format(itango)],
- "gui_scripts": ["itango-qt = PyTango.ipython:run_qt"]}
-
-
-def add_lib(name, dirs, sys_libs, env_name=None, lib_name=None, inc_suffix=None):
+def add_lib(name, dirs, sys_libs,
+ env_name=None, lib_name=None, inc_suffix=None):
if env_name is None:
env_name = name.upper() + '_ROOT'
ENV = os.environ.get(env_name)
@@ -167,15 +140,13 @@ def add_lib(name, dirs, sys_libs, env_name=None, lib_name=None, inc_suffix=None)
class build(dftbuild):
user_options = dftbuild.user_options + \
- [('without-ipython', None, "Tango IPython extension"),
- ('strip-lib', None, "strips the shared library of debugging symbols (Unix like systems only)"),
+ [('strip-lib', None, "strips the shared library of debugging symbols (Unix like systems only)"),
('no-doc', None, "do not build documentation") ]
- boolean_options = dftbuild.boolean_options + ['without-ipython', 'strip-lib', 'no-doc']
+ boolean_options = dftbuild.boolean_options + ['strip-lib', 'no-doc']
def initialize_options (self):
dftbuild.initialize_options(self)
- self.without_ipython = None
self.strip_lib = None
self.no_doc = None
@@ -188,12 +159,6 @@ class build(dftbuild):
elif get_c_numpy() is None:
self.warn("NOT using numpy: numpy available but C source is not")
- if IPython and not self.without_ipython:
- if V(IPython.__version__) > V('0.10'):
- self.distribution.py_modules.append('IPython.config.profile.tango.ipython_config')
- else:
- self.distribution.py_modules.append('IPython.Extensions.ipy_profile_tango')
-
dftbuild.run(self)
if self.strip_lib:
@@ -389,10 +354,6 @@ def setup_args():
packages = [
'PyTango',
- 'PyTango.ipython',
- 'PyTango.ipython.ipython_00_10',
- 'PyTango.ipython.ipython_00_11',
- 'PyTango.ipython.ipython_10_00',
'PyTango.databaseds',
'PyTango.databaseds.db_access',
]
@@ -414,16 +375,10 @@ def setup_args():
]
package_data = {
- 'PyTango' : [],
+ 'PyTango': [],
}
- scripts = get_script_files()
-
- entry_points = get_entry_points()
-
data_files = []
- if os.name == 'nt':
- data_files.append(('scripts', ['doc/_static/itango.ico']))
classifiers = [
'Development Status :: 5 - Production/Stable',
@@ -514,8 +469,6 @@ def setup_args():
classifiers=classifiers,
package_data=package_data,
data_files=data_files,
- scripts=scripts,
- entry_points=entry_points,
provides=provides,
keywords=Release.keywords,
requires=requires,
diff --git a/src/boost/python/ipython/__init__.py b/src/boost/python/ipython/__init__.py
deleted file mode 100644
index 360eb89..0000000
--- a/src/boost/python/ipython/__init__.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# -----------------------------------------------------------------------------
-# This file is part of PyTango (http://www.tinyurl.com/PyTango)
-#
-# Copyright 2006-2012 CELLS / ALBA Synchrotron, Bellaterra, Spain
-# Copyright 2013-2014 European Synchrotron Radiation Facility, Grenoble, France
-#
-# Distributed under the terms of the GNU Lesser General Public License,
-# either version 3 of the License, or (at your option) any later version.
-# See LICENSE.txt for more info.
-# -----------------------------------------------------------------------------
-
-__all__ = ["init_ipython", "install", "load_ipython_extension",
- "unload_ipython_extension", "load_config", "run", "run_qt"]
-
-from .common import get_python_version
-from .common import get_ipython_version
-from .common import get_pytango_version
-
-
-def default_init_ipython(*args, **kwargs):
- print("Unsupported IPython version (%s) for tango profile" \
- % get_ipython_version())
- print("Supported IPython versions are: >= 0.10")
- print("Starting normal IPython console...")
-
-def default_install(*args, **kwargs):
- print("Unsupported IPython version (%s) for tango profile" \
- % get_ipython_version())
- print("Supported IPython versions are: >= 0.10")
- print("Tango extension to IPython will NOT be installed.")
-
-init_ipython = default_init_ipython
-install = default_install
-is_installed = lambda : False
-
-__run = None
-__run_qt = None
-
-ipv = get_ipython_version()
-
-if ipv >= "0.10" and ipv < "0.11":
- from . import ipython_00_10
- init_ipython = ipython_00_10.init_ipython
- install = ipython_00_10.install
- is_installed = ipython_00_10.is_installed
- __run = ipython_00_10.run
- load_config = None
- load_ipython_extension = None
- unload_ipython_extension = None
-elif ipv >= "0.11" and ipv < "1.0":
- from . import ipython_00_11
- init_ipython = None
- install = ipython_00_11.install
- is_installed = ipython_00_11.is_installed
- __run = ipython_00_11.run
- load_config = ipython_00_11.load_config
- load_ipython_extension = ipython_00_11.load_ipython_extension
- unload_ipython_extension = ipython_00_11.unload_ipython_extension
-elif ipv >= "1.00":
- from . import ipython_10_00
- init_ipython = None
- install = ipython_10_00.install
- is_installed = ipython_10_00.is_installed
- __run = ipython_10_00.run
- load_config = ipython_10_00.load_config
- load_ipython_extension = ipython_10_00.load_ipython_extension
- unload_ipython_extension = ipython_10_00.unload_ipython_extension
-
-def run():
- if not is_installed():
- install(verbose=False)
- __run()
-
-def run_qt():
- if not is_installed():
- install(verbose=False)
- __run(qt=True)
\ No newline at end of file
diff --git a/src/boost/python/ipython/common.py b/src/boost/python/ipython/common.py
deleted file mode 100644
index 2ee7ada..0000000
--- a/src/boost/python/ipython/common.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python
-
-# -----------------------------------------------------------------------------
-# This file is part of PyTango (http://www.tinyurl.com/PyTango)
-#
-# Copyright 2006-2012 CELLS / ALBA Synchrotron, Bellaterra, Spain
-# Copyright 2013-2014 European Synchrotron Radiation Facility, Grenoble, France
-#
-# Distributed under the terms of the GNU Lesser General Public License,
-# either version 3 of the License, or (at your option) any later version.
-# See LICENSE.txt for more info.
-# -----------------------------------------------------------------------------
-
-"""functions common (hopefully) to all ipython versions"""
-
-__all__ = ["get_python_version",
- "get_ipython_version",
- "get_pytango_version"]
-
-import sys
-from distutils.version import StrictVersion
-
-#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
-# Python utilities
-#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
-
-def get_python_version():
- return StrictVersion('.'.join(map(str, sys.version_info[:3])))
-
-#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
-# IPython utilities
-#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
-
-def get_ipython_version():
- """Returns the current IPython version"""
- import IPython
- v = None
- if hasattr(IPython, "version_info"):
- v = '.'.join(map(str, IPython.version_info[:3]))
- else:
- try:
- try:
- v = IPython.Release.version
- except:
- try:
- v = IPython.release.version
- except:
- pass
- except:
- pass
- return StrictVersion(v)
-
-#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
-# PyTango utilities
-#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
-
-def get_pytango_version():
- try:
- import PyTango
- except:
- return
- try:
- v = PyTango.Release.version
- except:
- v = '0.0.0'
- return StrictVersion(v)
diff --git a/src/boost/python/ipython/eventlogger.py b/src/boost/python/ipython/eventlogger.py
deleted file mode 100644
index 3fc9ecd..0000000
--- a/src/boost/python/ipython/eventlogger.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# -----------------------------------------------------------------------------
-# This file is part of PyTango (http://www.tinyurl.com/PyTango)
-#
-# Copyright 2006-2012 CELLS / ALBA Synchrotron, Bellaterra, Spain
-# Copyright 2013-2014 European Synchrotron Radiation Facility, Grenoble, France
-#
-# Distributed under the terms of the GNU Lesser General Public License,
-# either version 3 of the License, or (at your option) any later version.
-# See LICENSE.txt for more info.
-# -----------------------------------------------------------------------------
-
-from __future__ import print_function
-
-import re
-import io
-import operator
-
-class EventLogger(object):
-
- def __init__(self, capacity=100000, pager=None):
- self._capacity = capacity
- self._pager = pager
- self._records = []
-
- def push_event(self, evt):
- attr_name = evt.attr_name
- dev, sep, attr = attr_name.rpartition('/')
- if dev.startswith("tango://"):
- dev = dev[8:]
- if dev.count(":"):
- # if it has tango host
- host, sep, dev = dev.partition('/')
- else:
- host = "-----"
- evt.host = host
- evt.dev_name = dev
- evt.s_attr_name = attr
- self._records.append(evt)
- over = len(self._records) - self._capacity
- if over > 0:
- self._records = self._records[over:]
-
- def model(self):
- return self
-
- def getEvents(self):
- return self._records
-
- def show(self, dexpr=None, aexpr=None):
- if dexpr is not None:
- dexpr = re.compile(dexpr, re.IGNORECASE)
- if aexpr is not None:
- aexpr = re.compile(aexpr, re.IGNORECASE)
-
- class StringIO(io.StringIO):
- def write(self, value):
- if isinstance(value, bytes):
- value = value.decode()
- io.StringIO.write(self, value)
-
- s = StringIO()
- lengths = 4, 30, 18, 20, 12, 16
- title = 'ID', 'Device', 'Attribute', 'Value', 'Quality', 'Time'
- templ = "{0:{l[0]}} {1:{l[1]}} {2:{l[2]}} {3:{l[3]}} {4:{l[4]}} {5:{l[5]}}"
- print(templ.format(*title, l=lengths), file=s)
- print(*map(operator.mul, lengths, len(lengths)*"-"), file=s)
-
- for i,r in enumerate(self._records):
- if dexpr is not None and not dexpr.match(r.dev_name): continue
- if aexpr is not None and not aexpr.match(r.s_attr_name): continue
- if r.err:
- v = r.errors[0].reason
- q = 'ERROR'
- ts = r.reception_date.strftime("%H:%M:%S.%f")
- else:
- v = str(r.attr_value.value)
- q = str(r.attr_value.quality)
- ts = r.attr_value.time.strftime("%H:%M:%S.%f")
- msg = templ.format(i, r.dev_name, r.s_attr_name, v, q, ts, l=lengths)
- print(msg, file=s)
- s.seek(0)
- if self._pager is None:
- print(s.read())
- else:
- self._pager(s.read())
diff --git a/src/boost/python/ipython/ipython_00_10/__init__.py b/src/boost/python/ipython/ipython_00_10/__init__.py
deleted file mode 100644
index 583c19a..0000000
--- a/src/boost/python/ipython/ipython_00_10/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# -----------------------------------------------------------------------------
-# This file is part of PyTango (http://www.tinyurl.com/PyTango)
-#
-# Copyright 2006-2012 CELLS / ALBA Synchrotron, Bellaterra, Spain
-# Copyright 2013-2014 European Synchrotron Radiation Facility, Grenoble, France
-#
-# Distributed under the terms of the GNU Lesser General Public License,
-# either version 3 of the License, or (at your option) any later version.
-# See LICENSE.txt for more info.
-# -----------------------------------------------------------------------------
-
-__all__ = ['init_ipython', 'install']
-
-from .ipython_00_10 import init_ipython, run
-from .ipy_install import install, is_installed
diff --git a/src/boost/python/ipython/ipython_00_10/ipy_install.py b/src/boost/python/ipython/ipython_00_10/ipy_install.py
deleted file mode 100644
index a8bc514..0000000
--- a/src/boost/python/ipython/ipython_00_10/ipy_install.py
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/usr/bin/env python
-
-# -----------------------------------------------------------------------------
-# This file is part of PyTango (http://www.tinyurl.com/PyTango)
-#
-# Copyright 2006-2012 CELLS / ALBA Synchrotron, Bellaterra, Spain
-# Copyright 2013-2014 European Synchrotron Radiation Facility, Grenoble, France
-#
-# Distributed under the terms of the GNU Lesser General Public License,
-# either version 3 of the License, or (at your option) any later version.
-# See LICENSE.txt for more info.
-# -----------------------------------------------------------------------------
-
-import sys
-import os
-
-import IPython.genutils
-import PyTango
-
-__PROFILE = """\
-#!/usr/bin/env ipython
-\"\"\"An automaticaly generated IPython profile designed to provide a user
-friendly interface to Tango.
-Created with PyTango {pytangover} for IPython {ipyver}\"\"\"
-
-import IPython
-import PyTango.ipython
-
-ip = IPython.ipapi.get()
-PyTango.ipython.init_ipython(ip)
-
-"""
-
-def is_installed(ipydir=None):
- install_dir = ipydir or IPython.genutils.get_ipython_dir()
- f_name = os.path.join(install_dir, 'ipy_profile_tango.py')
- return os.path.isfile(f_name)
-
-
-def install(ipydir=None, verbose=True, profile='tango'):
- install_dir = ipydir or IPython.genutils.get_ipython_dir()
- f_name = os.path.join(install_dir, 'ipy_profile_tango.py')
- if verbose:
- def out(msg):
- sys.stdout.write(msg)
- sys.stdout.flush()
- else:
- out = lambda x : None
-
- if ipydir is None and os.path.isfile(f_name):
- print("Warning: The file '%s' already exists." % f_name)
- r = ''
- while r.lower() not in ('y', 'n'):
- r = input("Do you wish to override it [Y/n]?")
- r = r or 'y'
- if r.lower() == 'n':
- return
- profile = __PROFILE.format(pytangover=PyTango.Release.version, ipyver=IPython.Release.version)
-
- out("Installing tango extension to ipython... ")
- try:
- f = open(f_name, "w")
- f.write(profile)
- f.close()
- out("[DONE]\n\n")
- except:
- out("[FAILED]\n\n")
- raise
-
- ipy_user_config = os.path.join(IPython.genutils.get_ipython_dir(), 'ipy_user_conf.py')
- out("""\
-To start ipython with tango interface simply type on the command line:
-%% ipython -p tango
-
-If you want tango extension to be automaticaly active when you start ipython,
-edit your {0} and add the line:
-import ipy_profile_tango
-
-Next time, just start ipython on the command line:
-%% ipython
-
-and your tango extension should be loaded automaticaly. Note that if you are also
-loading other extensions that, for example, overwrite the prompt, the prompt
-that will appear is the one from the last extension to be imported.
-
-For more information goto: http://www.tango-controls.org/static/PyTango/latest/doc/html/index.html
-
-Have fun with ITango!
-The PyTango team
- """.format(ipy_user_config))
-
-def main():
- d = None
- if len(sys.argv) > 1:
- d = sys.argv[1]
- install(d)
-
-if __name__ == "__main__":
- main()
diff --git a/src/boost/python/ipython/ipython_00_10/ipy_qt.py b/src/boost/python/ipython/ipython_00_10/ipy_qt.py
deleted file mode 100644
index 6ba06b6..0000000
--- a/src/boost/python/ipython/ipython_00_10/ipy_qt.py
+++ /dev/null
@@ -1,373 +0,0 @@
-# -----------------------------------------------------------------------------
-# This file is part of PyTango (http://www.tinyurl.com/PyTango)
-#
-# Copyright 2006-2012 CELLS / ALBA Synchrotron, Bellaterra, Spain
-# Copyright 2013-2014 European Synchrotron Radiation Facility, Grenoble, France
-#
-# Distributed under the terms of the GNU Lesser General Public License,
-# either version 3 of the License, or (at your option) any later version.
-# See LICENSE.txt for more info.
-# -----------------------------------------------------------------------------
-
-import logging
-import PyTango
-import PyQt4.Qt as Qt
-
-BRUSH = Qt.QBrush
-COLOR = Qt.QColor
-_WhiteBrush = Qt.QBrush(Qt.Qt.white)
-_BlackBrush = Qt.QBrush(Qt.Qt.black)
-_RedBrush = Qt.QBrush(Qt.Qt.red)
-_GreenBrush = Qt.QBrush(Qt.Qt.green)
-_DarkGreenBrush = Qt.QBrush(Qt.Qt.darkGreen)
-_BlueBrush = Qt.QBrush(Qt.Qt.blue)
-_YellowBrush = Qt.QBrush(Qt.Qt.yellow)
-_MagentaBrush = Qt.QBrush(Qt.Qt.magenta)
-_GrayBrush = Qt.QBrush(Qt.Qt.gray)
-_DarkGrayBrush = Qt.QBrush(Qt.Qt.darkGray)
-_LightGrayBrush = Qt.QBrush(Qt.Qt.lightGray)
-
-ATTR_QUALITY_DATA = {
- PyTango.AttrQuality.ATTR_INVALID : (BRUSH(COLOR(128, 128, 128)), _WhiteBrush),
- PyTango.AttrQuality.ATTR_VALID : (_GreenBrush, _BlackBrush),
- PyTango.AttrQuality.ATTR_ALARM : (BRUSH(COLOR(255, 140, 0)), _WhiteBrush),
- PyTango.AttrQuality.ATTR_WARNING : (BRUSH(COLOR(255, 140, 0)), _WhiteBrush),
- PyTango.AttrQuality.ATTR_CHANGING : (BRUSH(COLOR(128, 160, 255)), _BlackBrush),
- None : (BRUSH(Qt.Qt.FDiagPattern), _BlackBrush)
-}
-
-DEVICE_STATE_DATA = {
- PyTango.DevState.ON : (_GreenBrush, _BlackBrush),
- PyTango.DevState.OFF : (_WhiteBrush, _BlackBrush),
- PyTango.DevState.CLOSE : (_WhiteBrush, _DarkGreenBrush),
- PyTango.DevState.OPEN : (_GreenBrush, _BlackBrush),
- PyTango.DevState.INSERT : (_WhiteBrush, _BlackBrush),
- PyTango.DevState.EXTRACT : (_GreenBrush, _BlackBrush),
- PyTango.DevState.MOVING : (BRUSH(COLOR(128, 160, 255)), _BlackBrush),
- PyTango.DevState.STANDBY : (_YellowBrush, _BlackBrush),
- PyTango.DevState.FAULT : (_RedBrush, _BlackBrush),
- PyTango.DevState.INIT : (BRUSH(COLOR(204, 204, 122)), _BlackBrush),
- PyTango.DevState.RUNNING : (BRUSH(COLOR(128, 160, 255)), _BlackBrush),
- PyTango.DevState.ALARM : (BRUSH(COLOR(255, 140, 0)), _WhiteBrush),
- PyTango.DevState.DISABLE : (_MagentaBrush, _BlackBrush),
- PyTango.DevState.UNKNOWN : (_GrayBrush, _BlackBrush),
- None : (_GrayBrush, _BlackBrush),
-}
-
-def getBrushForQuality(q):
- return ATTR_QUALITY_DATA[q]
-
-def getBrushForState(s):
- return DEVICE_STATE_DATA[s]
-
-def deviceAttributeValueStr(da):
- return str(da.value)
-
-ID, HOST, DEVICE, ATTRIBUTE, VALUE, TIME = range(6)
-HORIZ_HEADER = 'ID', 'Host','Device','Attribute', 'Value', 'Time'
-
-class EventLoggerTableModel(Qt.QAbstractTableModel, logging.Handler):
-
- DftOddRowBrush = Qt.QBrush(Qt.QColor(220,220,220)), Qt.QBrush(Qt.Qt.black)
- DftEvenRowBrush = Qt.QBrush(Qt.QColor(255,255,255)), Qt.QBrush(Qt.Qt.black)
-
- DftColHeight = 20
-
- DftColSize = Qt.QSize(50, DftColHeight), Qt.QSize(120, DftColHeight), \
- Qt.QSize(160, DftColHeight), Qt.QSize(100, DftColHeight), \
- Qt.QSize(120, DftColHeight), Qt.QSize(120, DftColHeight)
-
- def __init__(self, capacity=20, freq=0.1):
- super(Qt.QAbstractTableModel, self).__init__()
- logging.Handler.__init__(self)
- self._capacity = capacity
- self._records = []
- self._accumulated_records = []
- self.startTimer(freq*1000)
-
- # ---------------------------------
- # Qt.QAbstractTableModel overwrite
- # ---------------------------------
-
-# def sort(self, column, order = Qt.Qt.AscendingOrder):
-# if column == LEVEL:
-# f = lambda a,b: cmp(a.levelno,b.levelno)
-# elif column == TYPE:
-# def f(a,b):
-# if not operator.isMappingType(a) or not operator.isMappingType(b):
-# return 0
-# return cmp(a.args.get('type','tau'), b.args.get('type','tau'))
-# elif column == TIME:
-# f = lambda a,b: cmp(a.created,b.created)
-# elif column == MSG:
-# f = lambda a,b: cmp(a.msg,b.msg)
-# elif column == NAME:
-# f = lambda a,b: cmp(a.name,b.name)
-# elif column == THREAD:
-# f = lambda a,b: cmp(a.threadName,b.threadName)
-# elif column == LOCALT:
-# f = lambda a,b: cmp(a.relativeCreated,b.relativeCreated)
-# self._records = sorted(self._records, cmp=f,reverse= order == Qt.Qt.DescendingOrder)
-# #self.reset()
-
- def rowCount(self, index=Qt.QModelIndex()):
- return len(self._records)
-
- def columnCount(self, index=Qt.QModelIndex()):
- return len(HORIZ_HEADER)
-
- def data(self, index, role=Qt.Qt.DisplayRole):
- if not index.isValid() or not (0 <= index.row() < len(self._records)):
- return Qt.QVariant()
- column, row = index.column(), index.row()
- record = self._records[row]
- if record.err:
- err = PyTango.DevFailed(*record.errors)
- else:
- err = None
- name = record.s_attr_name.lower()
- if role == Qt.Qt.DisplayRole:
- if column == ID:
- return Qt.QVariant(row)
- if column == HOST:
- return Qt.QVariant(record.host)
- elif column == DEVICE:
- return Qt.QVariant(record.dev_name)
- elif column == ATTRIBUTE:
- return Qt.QVariant(record.s_attr_name)
- elif column == VALUE:
- if err is None:
- return Qt.QVariant(deviceAttributeValueStr(record.attr_value))
- else:
- return Qt.QVariant(err[0].reason)
- elif column == TIME:
- if err is None:
- return Qt.QVariant(record.attr_value.time.strftime("%H:%M:%S.%f"))
- else:
- return Qt.QVariant(record.reception_date.strftime("%H:%M:%S.%f"))
- elif role == Qt.Qt.TextAlignmentRole:
- if column in (HOST, DEVICE, ATTRIBUTE):
- return Qt.QVariant(Qt.Qt.AlignLeft|Qt.Qt.AlignVCenter)
- return Qt.QVariant(Qt.Qt.AlignRight|Qt.Qt.AlignVCenter)
- elif role == Qt.Qt.BackgroundRole:
- if column == VALUE:
- if err is None:
- if name == "state":
- bg = getBrushForState(record.attr_value.value)[0]
- else:
- bg = getBrushForQuality(record.attr_value.quality)[0]
- else:
- bg = Qt.QBrush(Qt.Qt.red)
- else:
- if index.row() % 2:
- bg = self.DftOddRowBrush[0]
- else:
- bg = self.DftEvenRowBrush[0]
- return Qt.QVariant(bg)
- elif role == Qt.Qt.ForegroundRole:
- if column == VALUE:
- if err is None:
- if name == "state":
- fg = getBrushForState(record.attr_value.value)[1]
- else:
- fg = getBrushForQuality(record.attr_value.quality)[1]
- else:
- fg = Qt.QBrush(Qt.Qt.white)
- else:
- if index.row() % 2:
- fg = self.DftOddRowBrush[1]
- else:
- fg = self.DftEvenRowBrush[1]
- return Qt.QVariant(fg)
- elif role == Qt.Qt.ToolTipRole:
- if err is None:
- return Qt.QVariant(str(record.attr_value))
- else:
- return Qt.QVariant(str(record))
- elif role == Qt.Qt.SizeHintRole:
- return self._getSizeHint(column)
- #elif role == Qt.Qt.StatusTipRole:
- #elif role == Qt.Qt.CheckStateRole:
- elif role == Qt.Qt.FontRole:
- return Qt.QVariant(Qt.QFont("Mono", 8))
- return Qt.QVariant()
-
- def _getSizeHint(self, column):
- return Qt.QVariant(EventLoggerTableModel.DftColSize[column])
-
- def headerData(self, section, orientation, role=Qt.Qt.DisplayRole):
- if role == Qt.Qt.TextAlignmentRole:
- if orientation == Qt.Qt.Horizontal:
- return Qt.QVariant(int(Qt.Qt.AlignLeft | Qt.Qt.AlignVCenter))
- return Qt.QVariant(int(Qt.Qt.AlignRight | Qt.Qt.AlignVCenter))
- elif role == Qt.Qt.SizeHintRole:
- if orientation == Qt.Qt.Vertical:
- return Qt.QVariant(Qt.QSize(50, 20))
- else:
- return self._getSizeHint(section)
- elif role == Qt.Qt.FontRole:
- return Qt.QVariant(Qt.QFont("Mono", 8))
- elif role == Qt.Qt.ToolTipRole:
- if section == HOST:
- return Qt.QVariant("tango host")
- elif section == DEVICE:
- return Qt.QVariant("tango device")
- elif section == ATTRIBUTE:
- return Qt.QVariant("tango attribute")
- elif section == VALUE:
- return Qt.QVariant("attribute value")
- elif section == TIME:
- return Qt.QVariant("time stamp for the event")
- if role != Qt.Qt.DisplayRole:
- return Qt.QVariant()
- if orientation == Qt.Qt.Horizontal:
- return Qt.QVariant(HORIZ_HEADER[section])
- return Qt.QVariant(int(section+1))
-
- def insertRows(self, position, rows=1, index=Qt.QModelIndex()):
- self.beginInsertRows(Qt.QModelIndex(), position, position+rows-1)
- self.endInsertRows()
-
- def removeRows(self, position, rows=1, index=Qt.QModelIndex()):
- self.beginRemoveRows(Qt.QModelIndex(), position, position+rows-1)
- self.endRemoveRows()
-
- #def setData(self, index, value, role=Qt.Qt.DisplayRole):
- # pass
-
- #def flags(self, index)
- # pass
-
- #def insertColumns(self):
- # pass
-
- #def removeColumns(self):
- # pass
-
- # --------------------------
- # logging.Handler overwrite
- # --------------------------
-
- def timerEvent(self, evt):
- self.updatePendingRecords()
-
- def updatePendingRecords(self):
- if not self._accumulated_records:
- return
- row_nb = self.rowCount()
- records = self._accumulated_records
- self._accumulated_records = []
- self._records.extend(records)
- self.insertRows(row_nb, len(records))
- if len(self._records) > self._capacity:
- start = len(self._records) - self._capacity
- self._records = self._records[start:]
- self.removeRows(0, start)
-
- def push_event(self, evt):
- attr_name = evt.attr_name
- dev, sep, attr = attr_name.rpartition('/')
- if dev.startswith("tango://"):
- dev = dev[8:]
- if dev.count(":"):
- # if it has tango host
- host, sep, dev = dev.partition('/')
- else:
- host = "-----"
- evt.host = host
- evt.dev_name = dev
- evt.s_attr_name = attr
- self._accumulated_records.append(evt)
-
- def clearContents(self):
- self.removeRows(0, self.rowCount())
- self._records = []
- self._accumulated_records = []
-
- def getEvents(self):
- return self._records
-
-class EventLoggerTable(Qt.QTableView):
-
- DftScrollLock = False
-
- """A Qt table that displays the event logging messages"""
- def __init__(self, parent=None, model=None, designMode=False):
- super(EventLoggerTable, self).__init__(parent)
- self.setShowGrid(False)
- self.resetScrollLock()
- model = model or EventLoggerTableModel()
- self.setModel(model)
- hh = self.horizontalHeader()
- hh.setResizeMode(HOST, Qt.QHeaderView.Stretch)
- self.setSortingEnabled(False)
- #self.sortByColumn(TIME, Qt.Qt.AscendingOrder)
-
- def rowsInserted(self, index, start, end):
- """Overwrite of slot rows inserted to do proper resize and scroll to
- bottom if desired
- """
- for i in range(start,end+1):
- self.resizeRowToContents(i)
- if start == 0:
- self.resizeColumnsToContents()
- if not self._scrollLock:
- self.scrollToBottom()
-
- def setScrollLock(self, scrollLock):
- """Sets the state for scrollLock"""
- self._scrollLock = scrollLock
-
- def getScrollLock(self):
- """Returns wheater or not the scrollLock is active"""
- return self._scrollLock
-
- def resetScrollLock(self):
- self.setScrollLock(EventLoggerTable.DftScrollLock)
-
- def clearContents(self):
- self.model().clearContents()
-
- def getEvents(self):
- return self.model().getEvents()
-
- def sizeHint(self):
- return Qt.QSize(700, 400)
-
- #: Tells wheater the table should scroll automatically to the end each
- #: time a record is added or not
- autoScroll = Qt.pyqtProperty("bool", getScrollLock, setScrollLock, resetScrollLock)
-
-
-class EventLoggerWidget(Qt.QWidget):
-
- def __init__(self, parent=None, model=None, designMode=False):
- super(EventLoggerWidget, self).__init__(parent)
- self._model = model or EventLoggerTableModel()
- self.init(designMode)
-
- def init(self, designMode):
- l = Qt.QGridLayout()
- l.setContentsMargins(0,0,0,0)
- l.setVerticalSpacing(2)
- self.setLayout(l)
-
- table = self._logtable = EventLoggerTable(model = self._model, designMode=designMode)
- tb = self._toolbar = Qt.QToolBar("Event logger toolbar")
- tb.setFloatable(False)
-
- self._clearButton = Qt.QPushButton("Clear")
- Qt.QObject.connect(self._clearButton, Qt.SIGNAL("clicked()"), table.clearContents)
- tb.addWidget(self._clearButton)
- l.addWidget(tb, 0, 0)
- l.addWidget(table, 1, 0)
- l.setColumnStretch(0,1)
- l.setRowStretch(1,1)
-
- def model(self):
- return self._model
-
- def getEvents(self):
- return self.model().getEvents()
-
-EventLogger = EventLoggerWidget
\ No newline at end of file
diff --git a/src/boost/python/ipython/ipython_00_10/ipython_00_10.py b/src/boost/python/ipython/ipython_00_10/ipython_00_10.py
deleted file mode 100644
index accee70..0000000
--- a/src/boost/python/ipython/ipython_00_10/ipython_00_10.py
+++ /dev/null
@@ -1,969 +0,0 @@
-#!/usr/bin/env python
-
-# -----------------------------------------------------------------------------
-# This file is part of PyTango (http://www.tinyurl.com/PyTango)
-#
-# Copyright 2006-2012 CELLS / ALBA Synchrotron, Bellaterra, Spain
-# Copyright 2013-2014 European Synchrotron Radiation Facility, Grenoble, France
-#
-# Distributed under the terms of the GNU Lesser General Public License,
-# either version 3 of the License, or (at your option) any later version.
-# See LICENSE.txt for more info.
-# -----------------------------------------------------------------------------
-
-"""An IPython profile designed to provide a user friendly interface to Tango"""
-
-from __future__ import print_function
-
-import sys
-import os
-import re
-import io
-import textwrap
-import IPython.ipapi
-import IPython.ColorANSI
-import IPython.Prompts
-import IPython.PyColorize
-import IPython.excolors
-import IPython.ipstruct
-import IPython.genutils
-import PyTango
-import PyTango.utils
-
-_DB_SYMB = "db"
-_DFT_TANGO_HOST = None
-_TANGO_STORE = "__tango_store"
-_TANGO_ERR = "__tango_error"
-_PYTHON_ERR = "__python_error"
-_tango_init = False
-
-_TG_EXCEPTIONS = PyTango.DevFailed, PyTango.CommunicationFailed, \
- PyTango.NamedDevFailed, PyTango.NamedDevFailedList, \
- PyTango.WrongNameSyntax, PyTango.NonDbDevice, PyTango.WrongData, \
- PyTango.NonSupportedFeature, PyTango.AsynCall, \
- PyTango.AsynReplyNotArrived, PyTango.EventSystemFailed, \
- PyTango.DeviceUnlocked, PyTango.NotAllowed
-
-class DeviceClassCompleter(object):
- """Completer class that returns the list of devices of some class when
- called. """
-
- def __init__(self, klass, devices):
- self._klass = klass
- self._devices = devices
-
- def __call__(self, ip, evt):
- return self._devices
-
-
-# Rewrite DeviceProxy constructor because the database context that the user is
-# using may be different than the default TANGO_HOST. What we do is always append
-# the name of the database in usage to the device name given by the user (in case
-# he doesn't give a database name him(her)self, of course.
-#__DeviceProxy_init_orig__ = PyTango.DeviceProxy.__init__
-#def __DeviceProxy__init__(self, dev_name):
-# db = __get_db()
-# if db is None: return
-# if dev_name.count(":") == 0:
-# db_name = "%s:%s" % (db.get_db_host(), db.get_db_port())
-# dev_name = "%s/%s" % (db_name, dev_name)
-# __DeviceProxy_init_orig__(self, dev_name)
-#PyTango.DeviceProxy.__init__ = __DeviceProxy__init__
-
-#-------------------------------------------------------------------------------
-# Completers
-#-------------------------------------------------------------------------------
-
-def __DeviceProxy_completer(ip, evt):
- db = __get_db()
- if db is None: return
- ret = list(db._db_cache.devices.keys())
- ret.extend(db._db_cache.aliases.keys())
- return ret
-
-def __DeviceClass_completer(ip, evt):
- db = __get_db()
- if db is None: return
- return list(db._db_cache.klasses.keys())
-
-def __DeviceAlias_completer(ip, evt):
- db = __get_db()
- if db is None: return
- return list(db._db_cache.aliases.keys())
-
-def __AttributeAlias_completer(ip, evt):
- db = __get_db()
- if db is None: return
- return list(db._db_cache.attr_aliases.keys())
-
-def __PureDeviceProxy_completer(ip, evt):
- db = __get_db()
- if db is None: return
- return list(db._db_cache.devices.keys())
-
-def __AttributeProxy_completer(ip, evt):
- db = __get_db()
- if db is None: return
- cache = db._db_cache
-
- symb = evt.symbol
- n = symb.count("/")
- ret, devs, dev_aliases = None, cache.devices, cache.aliases
- # dev_list and dev_alias_list are case insensitive. They should only be used
- # to search for elements. Their elements are the same as the keys of the
- # dictionaries devs and dev_aliases respectively
- dev_list, dev_alias_list = cache.device_list, cache.alias_list
- dev_name = None
- if n == 0:
- # means it can be an attr alias, a device name has alias or as full device name
- ret = list(cache.get("attr_aliases").keys())
- ret.extend([ d+"/" for d in devs ])
- ret.extend([ d+"/" for d in dev_aliases ])
- # device alias found!
- if symb in dev_alias_list:
- dev_name = symb
- elif n == 1:
- # it can still be a full device name
- ret = [ d+"/" for d in devs ]
- # it can also be devalias/attr_name
- dev, attr = symb.split("/")
- if dev in dev_alias_list:
- dev_name = dev
- elif n == 2:
- # it is for sure NOT an attribute alias or a device alias
- ret = [ d+"/" for d in devs ]
- # device found!
- if symb in dev_list:
- dev_name = symb
- elif n == 3:
- # it is for sure a full attribute name
- dev, sep, attr = symb.rpartition("/")
- if dev in dev_list:
- dev_name = dev
-
- if dev_name is None:
- return ret
-
- try:
- d = __get_device_proxy(dev_name)
- # first check in cache for the attribute list
- if not hasattr(d, "_attr_list"):
- d._attr_list = d.get_attribute_list()
- if ret is None:
- ret = []
- ret.extend([ "%s/%s" % (dev_name, a) for a in d._attr_list ])
- except:
- # either DeviceProxy could not be created or device is not online
- pass
-
- return ret
-
-def __get_device_proxy(dev_name):
- db = __get_db()
- if db is None: return
- cache = db._db_cache
- from_alias = cache.aliases.get(dev_name)
-
- if from_alias is not None:
- dev_name = from_alias
-
- data = cache.devices.get(dev_name)
- if data is not None:
- d = data[3]
- if d is None:
- try:
- d = data[3] = PyTango.DeviceProxy(dev_name)
- except:
- pass
- return d
-
-def __get_device_subscriptions(dev_name):
- db = __get_db()
- if db is None: return
- cache = db._db_cache
- from_alias = cache.aliases.get(dev_name)
-
- if from_alias is not None:
- dev_name = from_alias
-
- data = cache.devices.get(dev_name)
- if data is not None:
- return data[4]
-
-def __switchdb_completer(ip, evt):
- return list(__get_store(ip, "database_list").keys())
-
-__monitor_completer = __AttributeProxy_completer
-
-#-------------------------------------------------------------------------------
-# Magic commands
-#-------------------------------------------------------------------------------
-
-def magic_refreshdb(self, parameter_s=''):
- init_db(IPython.ipapi.get(), parameter_s)
-
-def magic_switchdb(self, parameter_s=''):
- """Switches the active tango Database.
-
- Usage: switchdb <host>[(:| )<port>]
-
- <port> is optional. If not given it defaults to 10000.
-
- Examples:
- In [1]: switchdb homer:10005
- In [2]: switchdb homer 10005
- In [3]: switchdb homer"""
-
- if parameter_s == '':
- raise IPython.ipapi.UsageError("%switchdb: Must specify a tango database name. See '%switchdb?'")
- return init_db(IPython.ipapi.get(), parameter_s)
-
-def magic_lsdev(self, parameter_s=''):
- """Lists all known tango devices.
-
- Usage: lsdev [<device name filter(regular expression)]
-
- Examples:
- In [1]: lsdev
- In [2]: lsdev sys.*"""
-
- if parameter_s:
- reg_exp = re.compile(parameter_s, re.IGNORECASE)
- else:
- reg_exp = None
-
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database. Device list is empty")
- return
- data = db._db_cache.devices
-
- s = io.StringIO()
- cols = 40, 25, 25, 20
- l = "%{0}s %{1}s %{2}s %{3}s".format(*cols)
- print(l % ("Device", "Alias", "Server", "Class"), file=s)
- print(l % (cols[0]*"-", cols[1]*"-", cols[2]*"-", cols[3]*"-"), file=s)
- for d, v in data.items():
- if reg_exp and not reg_exp.match(d): continue
- print(l % (d, v[0], v[1], v[2]), file=s)
- s.seek(0)
- IPython.genutils.page(s.read())
-
-def magic_lsdevclass(self, parameter_s=''):
- """Lists all known tango device classes.
-
- Usage: lsdevclass [<class name filter(regular expression)]
-
- Examples:
- In [1]: lsdevclass
- In [2]: lsdevclass Motor.*"""
-
- if parameter_s:
- reg_exp = re.compile(parameter_s, re.IGNORECASE)
- else:
- reg_exp = None
-
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database. Device class list is empty")
- return
- data = db._db_cache.klasses
-
- data = [ "%-030s" % klass for klass in data.keys() if not reg_exp or reg_exp.match(klass) ]
- s = textwrap.fill(" ".join(data), 80)
- IPython.genutils.page(s)
-
-def magic_lsserv(self, parameter_s=''):
- """Lists all known tango servers.
-
- Usage: lsserv [<class name filter(regular expression)]
-
- Examples:
- In [1]: lsserv
- In [2]: lsserv Motor/.*"""
-
- if parameter_s:
- reg_exp = re.compile(parameter_s, re.IGNORECASE)
- else:
- reg_exp = None
-
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database. Device class list is empty")
- return
- data = db._db_cache.servers
-
- data = [ "%-030s" % server for server in data.keys() if not reg_exp or reg_exp.match(server) ]
- s = textwrap.fill(" ".join(data), 80)
- IPython.genutils.page(s)
-
-def magic_tango_error(self, parameter_s=''):
- """Displays detailed information about the last tango error"""
-
- global _TANGO_ERR
- err_info = self.user_ns.get(_TANGO_ERR)
- if err_info is None:
- print("No tango error reported so far.")
- return
- print("Last tango error:")
- print(err_info[1])
-
-def magic_python_error(self, parameter_s=''):
- """Displays detailed information about the last python error"""
-
- global _PYTHON_ERR
- err_info = self.user_ns.get(_PYTHON_ERR)
- if err_info is None:
- print("No error reported so far.")
- return
- ip = IPython.ipapi.get()
- etype, evalue, etb = err_info[:3]
- ip.IP.InteractiveTB(etype=etype, evalue=evalue, etb=etb, tb_offset=None)
-
-_EVT_LOG = None
-def __get_event_log():
- global _EVT_LOG
- if _EVT_LOG is None:
- import PyTango.ipython.eventlogger
- _EVT_LOG = PyTango.ipython.eventlogger.EventLogger(capacity=10000, pager=IPython.genutils.page)
- return _EVT_LOG
-
-def magic_mon(self, parameter_s=''):
- """Monitor a given attribute.
-
- %mon -a <attribute name> - activates monitoring of given attribute
- %mon -d <attribute name> - deactivates monitoring of given attribute
- %mon -r - deactivates monitoring of all attributes
- %mon -i <id> - displays detailed information for the event with given id
- %mon -l <dev filter> <attr filter> - shows event table filtered with the regular expression for attribute name
- %mon - shows event table (= %mon -i .* .*)"""
-
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- opts, args = self.parse_options(parameter_s,'adril', mode='list')
- if len(args) > 3:
- raise IPython.ipapi.UsageError("%mon: too many arguments")
- if 'd' in opts:
- try:
- todel = args[0]
- except IndexError:
- raise IPython.ipapi.UsageError(
- "%mon -d: must provide an attribute to unmonitor")
- else:
- try:
- dev, sep, attr = todel.rpartition("/")
- subscriptions = __get_device_subscriptions(dev)
- id = subscriptions[attr.lower()]
- del subscriptions[attr.lower()]
- d = __get_device_proxy(dev)
- d.unsubscribe_event(id)
- print("Stopped monitoring '%s'" % todel)
- except KeyError:
- raise IPython.ipapi.UsageError(
- "%%mon -d: Not monitoring '%s'" % todel)
-
- elif 'a' in opts:
- try:
- toadd = args[0]
- except IndexError:
- raise IPython.ipapi.UsageError(
- "%mon -a: must provide an attribute to monitor")
- dev, sep, attr = toadd.rpartition("/")
- subscriptions = __get_device_subscriptions(dev)
- id = subscriptions.get(attr.lower())
- if id is not None:
- raise IPython.ipapi.UsageError(
- "%%mon -a: Already monitoring '%s'" % toadd)
- d = __get_device_proxy(dev)
- w = __get_event_log()
- model = w.model()
- id = d.subscribe_event(attr, PyTango.EventType.CHANGE_EVENT, model, [])
- subscriptions[attr.lower()] = id
- print("'%s' is now being monitored. Type 'mon' to see all events" % toadd)
- elif 'r' in opts:
- for d, v in db._db_cache.devices.items():
- d, subs = v[3], v[4]
- for id in subs.values():
- d.unsubscribe_event(id)
- v[4] = {}
- elif 'i' in opts:
- try:
- evtid = int(args[0])
- except IndexError:
- raise IPython.ipapi.UsageError(
- "%mon -i: must provide an event ID")
- except ValueError:
- raise IPython.ipapi.UsageError(
- "%mon -i: must provide a valid event ID")
- try:
- w = __get_event_log()
- e = w.getEvents()[evtid]
- if e.err:
- print(str(PyTango.DevFailed(*e.errors)))
- else:
- print(str(e))
- except IndexError:
- raise IPython.ipapi.UsageError(
- "%mon -i: must provide a valid event ID")
- elif 'l' in opts:
- try:
- dexpr = args[0]
- aexpr = args[1]
- except IndexError:
- raise IPython.ipapi.UsageError(
- "%mon -l: must provide valid device and attribute filters")
- w = __get_event_log()
- w.show(dexpr, aexpr)
- else:
- w = __get_event_log()
- w.show()
-
-#-------------------------------------------------------------------------------
-# Useful functions (not magic commands but accessible from CLI as normal python
-# functions)
-#-------------------------------------------------------------------------------
-
-def get_device_map():
- """Returns a dictionary where keys are device names and value is a sequence
- of 4 elements:
- - alias name (empty string if no alias is defined)
- - tango server name (full tango server name <name>/<instance>)
- - tango class name
- - DeviceProxy to the device or None if it hasn't been initialized yet
- (this last element is for internal tango usage only. If you need a
- DeviceProxy to this device, create your own)"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.devices
-
-def get_server_map():
- """Returns a dictionary where keys are server names (<name>/<instance>)
- and value is a sequence of device names that belong to the server"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.servers
-
-def get_class_map():
- """Returns a dictionary where keys are the tango classes and value is a
- sequence of device names that belong to the tango class"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.klasses
-
-def get_alias_map():
- """Returns a dictionary where keys are the tango device aliases and value
- is a the tango device name"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.aliases
-
-def get_device_list():
- """Returns a case insensitive list of device names for the current
- database"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.device_list
-
-def get_alias_list():
- """Returns a case insensitive list of device aliases for the current
- database"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.alias_list
-
-#-------------------------------------------------------------------------------
-# Private helper methods
-#-------------------------------------------------------------------------------
-
-def __exc_handler(ip, etype, value, tb):
- global _TG_EXCEPTIONS
- if etype in _TG_EXCEPTIONS:
- global _TANGO_ERR
- ip.user_ns[_TANGO_ERR] = etype, value, tb
- if len(value.args):
- v = value[0]
- print("%s: %s" % (v.reason ,v.desc))
- else:
- print("Empty DevFailed")
- print("(For more detailed information type: tango_error)")
- else:
- global _PYTHON_ERR
- ip.user_ns[_PYTHON_ERR] = etype, value, tb
- print(etype.__name__ + ": " + str(value))
- print("(For more detailed information type: python_error)")
-
-def __get_default_tango_host():
- global _DFT_TANGO_HOST
- if _DFT_TANGO_HOST is None:
- try:
- db = PyTango.Database()
- _DFT_TANGO_HOST = "%s:%s" % (db.get_db_host(), db.get_db_port())
- except:
- pass
- return _DFT_TANGO_HOST
-
-def __get_db(host_port=None):
- """host_port == None: Use current DB whatever it is or create
- default if doesn't exist
- host_port == '' : use default db. If it is not the current db, switch
- current db to it and return it
- host_port == ... : if ... is not the current db, switch current db to it
- and return it
- """
-
- ip = IPython.ipapi.get()
- global _DB_SYMB
- db = ip.user_ns.get(_DB_SYMB)
-
- if host_port is None:
- if db is None:
- host_port = __get_default_tango_host()
- elif host_port == '':
- host_port = __get_default_tango_host()
- else:
- host_port = host_port.strip().replace(" ",":")
- if host_port.count(":") == 0:
- host_port += ":10000"
-
- if host_port is not None:
- host_port = str(host_port)
-
- if db is None:
- create_db = True
- elif host_port is None:
- create_db = False
- else:
- old_host_port = "%s:%s" % (db.get_db_host(), db.get_db_port())
- create_db = old_host_port != host_port
-
- if create_db:
- try:
- db = PyTango.Database(*host_port.split(":"))
-
- ip.user_ns["DB_NAME"] = host_port
- except Exception:
- print()
- if db:
- print("Could not access Database", host_port)
- old_host_port = "%s:%s" % (db.get_db_host(), db.get_db_port())
- print("Maintaining connection to Database", old_host_port)
- ip.user_ns["DB_NAME"] = old_host_port
- else:
- print("Could not access any Database.")
- print("Make sure .tangorc, /etc/tangorc or TANGO_HOST environment is defined.")
- ip.user_ns["DB_NAME"] = "OFFLINE"
-
- # register the 'db' in the user namespace
- ip.to_user_ns({ _DB_SYMB : db })
-
- return db
-
-def __get_obj_name(o):
- try:
- n = o.__name__
- except:
- try:
- n = o.__class__.__name__
- except:
- n = "<unknown>"
- return n
-
-def __completer_wrapper(f):
- def wrapper(ip, evt):
- try:
- return f(ip, evt)
- except Exception as e:
- print()
- print("An unexpected exception ocorred during ITango command completer.")
- print("Please send a bug report to the PyTango team with the following informantion:")
- print(IPython.ipapi.get().options.banner)
- print(80*"-")
- print("Completer:",__get_obj_name(f))
- print(80*"-")
- print(str(e))
- print(80*"-")
- raise e
- return wrapper
-
-def __get_ipapi():
- return IPython.ipapi.get()
-
-def __expose_magic(ip, name, fn, completer_func=None):
- ip.expose_magic(name, fn)
-
- if completer_func is None:
- return
-
- # enable macro param completion
- ip.set_hook('complete_command', completer_func, re_key = ".*" + name)
-
-def __unexpose_magic(ip, name):
- mg = 'magic_%s' % name
- delattr(ip.IP, mg)
-
-def __build_color_scheme(ip, name):
-
- # make some schemes as instances so we can copy them for modification easily:
- ColorANSI = IPython.ColorANSI
- InputColors = ColorANSI.InputTermColors
- TermColors = ColorANSI.TermColors
- PromptColors = IPython.Prompts.PromptColors
- ANSICodeColors = IPython.PyColorize.ANSICodeColors
- ExceptionColors = IPython.excolors.ExceptionColors
- TBColors = ip.IP.InteractiveTB.color_scheme_table
- SyntaxColors = ip.IP.SyntaxTB.color_scheme_table
- InspectColors = IPython.OInspect.InspectColors
-
- promptTangoColors = PromptColors['Linux'].copy(name)
- ANSITangoColors = ANSICodeColors['Linux'].copy(name)
- exceptionTangoColors = ExceptionColors['Linux'].copy(name)
- TBTangoColors = TBColors['Linux'].copy(name)
- syntaxTangoColors = SyntaxColors['Linux'].copy(name)
- inspectTangoColors = InspectColors['Linux'].copy(name)
-
- # initialize prompt with default tango colors
- promptTangoColors.colors.in_prompt = InputColors.Purple
- promptTangoColors.colors.in_number = InputColors.LightPurple
- promptTangoColors.colors.in_prompt2 = InputColors.Purple
- promptTangoColors.colors.out_prompt = TermColors.Blue
- promptTangoColors.colors.out_number = TermColors.LightBlue
-
- ret= { "prompt" : (PromptColors, promptTangoColors),
- "ANSI" : (ANSICodeColors, ANSITangoColors),
- "except" : (ExceptionColors, exceptionTangoColors),
- "TB" : (TBColors, TBTangoColors),
- "Syntax" : (SyntaxColors, syntaxTangoColors),
- "Inspect": (InspectColors, inspectTangoColors) }
-
- if ip.IP.isthreaded:
- TBThreadedColors = ip.IP.sys_excepthook.color_scheme_table
- TBThreadedTangoColors = TBThreadedColors['Linux'].copy(name)
- ret["TBThreaded"] = TBThreadedColors, TBThreadedTangoColors
- return ret
-
-def __set_store(ip, key=None, value=None):
- if key is not None:
- tango_store = ip.user_ns.get(_TANGO_STORE)
- tango_store[key] = value
- __store(ip, _TANGO_STORE)
-
-def __get_store(ip, key, nvalue=None):
- tango_store = ip.user_ns.get(_TANGO_STORE)
- v = tango_store.get(key)
- if v is None and nvalue is not None:
- tango_store[key] = nvalue
- v = nvalue
- return v
-
-def __store(ip, var):
- # this executes the magic command store which prints a lot of info. So, first
- # we hide the standard output
- stdout = sys.stdout
- try:
- sys.stdout = io.StringIO()
- ip.magic("store %s" % var)
- finally:
- sys.stdout = stdout
-
-#-------------------------------------------------------------------------------
-# Initialization methods
-#-------------------------------------------------------------------------------
-
-def init_colors(ip):
- ColorANSI = IPython.ColorANSI
- InputColors = ColorANSI.InputTermColors
- TermColors = ColorANSI.TermColors
-
- name = "Tango"
- scheme = __build_color_scheme(ip, name)
- for k, v in scheme.items():
- v[0].add_scheme(v[1])
-
- name = "PurpleTango"
- scheme = __build_color_scheme(ip, name)
- for k, v in scheme.items():
- v[0].add_scheme(v[1])
-
- name = "BlueTango"
- scheme = __build_color_scheme(ip, name)
- prompt = scheme["prompt"][1]
- prompt.colors.in_prompt = InputColors.Blue
- prompt.colors.in_number = InputColors.LightBlue
- prompt.colors.in_prompt2 = InputColors.Blue
- prompt.colors.out_prompt = TermColors.Cyan
- prompt.colors.out_number = TermColors.LightCyan
- for k, v in scheme.items():
- v[0].add_scheme(v[1])
-
- name = "GreenTango"
- scheme = __build_color_scheme(ip, name)
- prompt = scheme["prompt"][1]
- prompt.colors.in_prompt = InputColors.Green
- prompt.colors.in_number = InputColors.LightGreen
- prompt.colors.in_prompt2 = InputColors.Green
- prompt.colors.out_prompt = TermColors.Red
- prompt.colors.out_number = TermColors.LightRed
- for k, v in scheme.items():
- v[0].add_scheme(v[1])
-
-def init_pytango(ip):
- """Initializes the IPython environment with PyTango elements"""
-
- # export symbols to IPython namepspace
- ip.ex("import PyTango")
- ip.ex("from PyTango import DeviceProxy, AttributeProxy, Database, Group")
- ip.ex("Device = DeviceProxy")
- ip.ex("Attribute = AttributeProxy")
-
- # add completers
- dp_completer = __completer_wrapper(__DeviceProxy_completer)
- attr_completer = __completer_wrapper(__AttributeProxy_completer)
- ip.set_hook('complete_command', dp_completer, re_key = ".*DeviceProxy[^\w\.]+")
- ip.set_hook('complete_command', dp_completer, re_key = ".*Device[^\w\.]+")
- ip.set_hook('complete_command', attr_completer, re_key = ".*AttributeProxy[^\w\.]+")
- ip.set_hook('complete_command', attr_completer, re_key = ".*Attribute[^\w\.]+")
-
- ip.set_custom_exc((Exception,), __exc_handler)
-
-def init_db(ip, parameter_s=''):
- global _DB_SYMB
- old_db = ip.user_ns.get(_DB_SYMB)
-
- db = __get_db(parameter_s)
-
- if old_db is not None and hasattr(old_db, "_db_cache"):
- old_junk = old_db._db_cache["junk"].keys()
- for e in old_junk:
- del ip.user_ns[e]
- else:
- old_junk = ()
-
- if db is None: return
-
- #os.environ["TANGO_HOST"] = "%s:%s" % (db.get_db_host(), db.get_db_port())
-
- # Initialize device and server information
- query = "SELECT name, alias, server, class FROM device order by name"
-
- r = db.command_inout("DbMySqlSelect", query)
- row_nb, column_nb = r[0][-2], r[0][-1]
- results, data = r[0][:-2], r[1]
- assert row_nb == len(data) / column_nb
- devices, aliases, servers, klasses = data[0::4], data[1::4], data[2::4], data[3::4]
-
- #CD = PyTango.utils.CaselessDict
- CD = dict
- dev_dict, serv_dict, klass_dict, alias_dict = CD(), CD(), CD(), CD()
-
- for device, alias, server, klass in zip(devices, aliases, servers, klasses):
- dev_lower = device.lower()
-
- # hide dserver devices
- if dev_lower.startswith("dserver/"): continue
-
- # hide alias that start with "_"
- if alias and alias[0] == "_": alias = ''
-
- # last None below is to be filled by DeviceProxy object on demand
- # last empty dict<str, int> where keys is attribute name and value is
- # the subscription id
- dev_dict[device] = [alias, server, klass, None, {}]
- serv_devs = serv_dict.get(server)
- if serv_devs is None:
- serv_dict[server] = serv_devs = []
- serv_devs.append(device)
- klass_devs = klass_dict.get(klass)
- if klass_devs is None:
- klass_dict[klass] = klass_devs = []
- klass_devs.append(device)
- if len(alias):
- alias_dict[alias] = device
- serv_devs.append(alias)
- klass_devs.append(alias)
-
- exposed_klasses = {}
- excluded_klasses = "DServer",
- for klass, devices in klass_dict.items():
- if klass in excluded_klasses: continue
- if klass not in ip.user_ns or klass in old_junk:
- c = DeviceClassCompleter(klass, devices)
- ip.set_hook('complete_command', c, re_key = ".*" + klass + "[^\w\.]+")
- exposed_klasses[klass] = PyTango.DeviceProxy
-
- # expose classes no user namespace
- ip.to_user_ns(exposed_klasses)
-
- # Initialize attribute information
- query = "SELECT name, alias FROM attribute_alias order by alias"
-
- r = db.command_inout("DbMySqlSelect", query)
- row_nb, column_nb = r[0][-2], r[0][-1]
- results, data = r[0][:-2], r[1]
- assert row_nb == len(data) / column_nb
- attributes, aliases = data[0::2], data[1::2]
-
- attr_alias_dict = {}
- for attribute, alias in zip(attributes, aliases):
- if len(alias):
- attr_alias_dict[alias] = attribute
-
- device_list = PyTango.utils.CaselessList(dev_dict.keys())
- alias_list = PyTango.utils.CaselessList(alias_dict.keys())
- attr_alias_list = PyTango.utils.CaselessList(attr_alias_dict.keys())
-
- # Build cache
- db_cache = IPython.ipstruct.Struct(devices=dev_dict, aliases=alias_dict,
- servers=serv_dict, klasses=klass_dict,
- junk=exposed_klasses,
- attr_aliases=attr_alias_dict,
- device_list=device_list,
- alias_list=alias_list,
- attr_alias_list=attr_alias_list)
-
- db._db_cache = db_cache
-
- # Add this DB to the list of known DBs (for possible use in magic commands)
- valid_dbs = __get_store(ip, "database_list", {})
- if db.get_db_port_num() == 10000:
- db_name = db.get_db_host()
- else:
- db_name = "%s:%s" % (db.get_db_host(), db.get_db_port())
- valid_dbs[db_name] = None
- __set_store(ip)
-
- return db
-
-def init_store(ip):
- # recover the environment
- ip.magic("store -r")
- tango_store = ip.user_ns.get(_TANGO_STORE)
-
- if tango_store is None:
- print("Initializing tango store (should only happen once)")
- tango_store = {}
- ip.to_user_ns( { _TANGO_STORE : tango_store} )
- __store(ip, _TANGO_STORE)
-
-def init_console(ip):
- import PyTango.ipython
-
- TermColors = IPython.ColorANSI.TermColors
-
- d = { "version" : str(PyTango.ipython.get_pytango_version()),
- "pyver" : str(PyTango.ipython.get_python_version()),
- "ipyver" : str(PyTango.ipython.get_ipython_version()),
- "pytangover" : str(PyTango.ipython.get_pytango_version()) }
- d.update(TermColors.__dict__)
-
- o = ip.options
-
- so = IPython.ipstruct.Struct(
- tango_banner = """%(Blue)shint: Try typing: mydev = Device("%(LightBlue)s<tab>%(Normal)s\n""")
-
- so = ip.user_ns.get("tango_options", so)
-
- #o.colors = "Tango"
- o.prompt_in1 = "ITango [\\#]: "
- o.prompt_out = "Result [\\#]: "
- banner = """
-%(Purple)sITango %(version)s%(Normal)s -- An interactive %(Purple)sTango%(Normal)s client.
-
-Running on top of Python %(pyver)s, IPython %(ipyver)s and PyTango %(pytangover)s
-
-help -> ITango's help system.
-object? -> Details about 'object'. ?object also works, ?? prints more.
-
-""" + so.tango_banner
- o.banner = banner % d
- if hasattr(o.banner, "format"):
- o.banner = o.banner.format(**d)
-
-def init_magic(ip):
- __expose_magic(ip, "refreshdb", magic_refreshdb)
- __expose_magic(ip, "reloaddb", magic_refreshdb)
- __expose_magic(ip, "switchdb", magic_switchdb, __switchdb_completer)
- __expose_magic(ip, "lsdev", magic_lsdev)
- __expose_magic(ip, "lsdevclass", magic_lsdevclass)
- __expose_magic(ip, "lsserv", magic_lsserv)
- __expose_magic(ip, "tango_error", magic_tango_error)
- __expose_magic(ip, "python_error", magic_python_error)
- __expose_magic(ip, "mon", magic_mon, __monitor_completer)
- #__expose_magic(ip, "umon", magic_umon, __monitor_completer)
-
- ip.to_user_ns({"get_device_map" : get_device_map,
- "get_server_map" : get_server_map,
- "get_class_map" : get_class_map,
- "get_alias_map" : get_alias_map,
- "get_device_list" : get_device_list,
- "get_alias_list" : get_alias_list})
-
- #__expose_magic(ip, "get_device_map", get_device_map)
- #__expose_magic(ip, "get_server_map", get_server_map)
- #__expose_magic(ip, "get_class_map", get_class_map)
- #__expose_magic(ip, "get_alias_map", get_alias_map)
- #__expose_magic(ip, "get_device_list", get_device_list)
- #__expose_magic(ip, "get_alias_list", get_alias_list)
-
-def complete(text):
- """a super complete!!!!"""
- self = IPython.ipapi.get().IP
- complete = self.Completer.complete
- state = 0
- comps = set()
- while True:
- newcomp = complete("", state, line_buffer=text)
- if newcomp is None:
- break
- comps.add(newcomp)
- state += 1
- outcomps = sorted(comps)
- return outcomps
-
-def init_ipython(ip, store=True, pytango=True, colors=True, console=True, magic=True):
-
- if ip is None:
- raise Exception("ITango's init_ipython must be called from inside IPython")
-
- global _tango_init
- if _tango_init is True: return
-
- #ip.IP._orig_complete = ip.IP.complete
- #ip.IP.complete = complete
-
- if colors: init_colors(ip)
- if store: init_store(ip)
- if pytango: init_pytango(ip)
- init_db(ip)
- if console: init_console(ip)
- if magic: init_magic(ip)
-
- _tango_init = True
-
-def run():
- argv = sys.argv
-
- try:
- for i, arg in enumerate(argv[:1]):
- if arg.startswith('--profile='):
- break
- else:
- argv.append("--profile=tango")
- except:
- pass
-
- shell = IPython.Shell.start()
- shell.mainloop()
diff --git a/src/boost/python/ipython/ipython_00_11/__init__.py b/src/boost/python/ipython/ipython_00_11/__init__.py
deleted file mode 100644
index 4bafc48..0000000
--- a/src/boost/python/ipython/ipython_00_11/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# -----------------------------------------------------------------------------
-# This file is part of PyTango (http://www.tinyurl.com/PyTango)
-#
-# Copyright 2006-2012 CELLS / ALBA Synchrotron, Bellaterra, Spain
-# Copyright 2013-2014 European Synchrotron Radiation Facility, Grenoble, France
-#
-# Distributed under the terms of the GNU Lesser General Public License,
-# either version 3 of the License, or (at your option) any later version.
-# See LICENSE.txt for more info.
-# -----------------------------------------------------------------------------
-
-__all__ = ['load_ipython_extension', 'unload_ipython_extension', 'load_config',
- 'run', 'install', 'is_installed']
-
-from .ipython_00_11 import load_ipython_extension, unload_ipython_extension, \
- load_config, run
-from .ipy_install import install, is_installed
-
diff --git a/src/boost/python/ipython/ipython_00_11/ipy_install.py b/src/boost/python/ipython/ipython_00_11/ipy_install.py
deleted file mode 100644
index cbf09a0..0000000
--- a/src/boost/python/ipython/ipython_00_11/ipy_install.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/env python
-
-# -----------------------------------------------------------------------------
-# This file is part of PyTango (http://www.tinyurl.com/PyTango)
-#
-# Copyright 2006-2012 CELLS / ALBA Synchrotron, Bellaterra, Spain
-# Copyright 2013-2014 European Synchrotron Radiation Facility, Grenoble, France
-#
-# Distributed under the terms of the GNU Lesser General Public License,
-# either version 3 of the License, or (at your option) any later version.
-# See LICENSE.txt for more info.
-# -----------------------------------------------------------------------------
-
-from __future__ import with_statement
-
-import sys
-import os
-import io
-
-import IPython
-from IPython.core.profiledir import ProfileDirError, ProfileDir
-from IPython.core.application import BaseIPythonApplication
-from IPython.utils.path import get_ipython_dir
-from IPython.utils.io import ask_yes_no
-
-import PyTango
-
-
-__PROFILE = """\
-#!/usr/bin/env ipython
-\"\"\"An automaticaly generated IPython profile designed to provide a user
-friendly interface to Tango.
-Created with PyTango {pytangover} for IPython {ipyver}\"\"\"
-
-import PyTango.ipython
-
-config = get_config()
-PyTango.ipython.load_config(config)
-
-# Put any additional environment here
-"""
-
-_CONFIG_FILE_NAME = 'ipython_config.py'
-
-def is_installed(ipydir=None, profile='tango'):
- ipython_dir = ipydir or get_ipython_dir()
- try:
- p_dir = ProfileDir.find_profile_dir_by_name(ipython_dir, profile)
- except ProfileDirError:
- return False
- abs_config_file_name = os.path.join(p_dir.location, _CONFIG_FILE_NAME)
- return os.path.isfile(abs_config_file_name)
-
-def install(ipydir=None, verbose=True, profile='tango'):
- if verbose:
- def out(msg):
- sys.stdout.write(msg)
- sys.stdout.flush()
- else:
- out = lambda x : None
-
- ipython_dir = ipydir or get_ipython_dir()
- try:
- p_dir = ProfileDir.find_profile_dir_by_name(ipython_dir, profile)
- except ProfileDirError:
- p_dir = ProfileDir.create_profile_dir_by_name(ipython_dir, profile)
- abs_config_file_name = os.path.join(p_dir.location, _CONFIG_FILE_NAME)
- create_config = True
- if os.path.isfile(abs_config_file_name):
- create_config = ask_yes_no("Tango configuration file already exists. "\
- "Do you wish to replace it?", default='y')
-
- if not create_config:
- return
-
- out("Installing tango extension to ipython... ")
-
- profile = __PROFILE.format(pytangover=PyTango.Release.version,
- ipyver=IPython.release.version)
- with open(abs_config_file_name, "w") as f:
- f.write(profile)
- f.close()
- out("[DONE]\n\n")
- out("""\
-To start ipython with tango interface simply type on the command line:
-%% ipython --profile=tango
-
-For more information goto:
-http://www.tango-controls.org/static/PyTango/latest/doc/html/
-
-Have fun with ITango!
-The PyTango team
-""")
-
-def main():
- d = None
- if len(sys.argv) > 1:
- d = sys.argv[1]
- install(d)
-
-if __name__ == "__main__":
- main()
diff --git a/src/boost/python/ipython/ipython_00_11/ipython_00_11.py b/src/boost/python/ipython/ipython_00_11/ipython_00_11.py
deleted file mode 100644
index ad4cd69..0000000
--- a/src/boost/python/ipython/ipython_00_11/ipython_00_11.py
+++ /dev/null
@@ -1,1269 +0,0 @@
-#!/usr/bin/env python
-
-# -----------------------------------------------------------------------------
-# This file is part of PyTango (http://www.tinyurl.com/PyTango)
-#
-# Copyright 2006-2012 CELLS / ALBA Synchrotron, Bellaterra, Spain
-# Copyright 2013-2014 European Synchrotron Radiation Facility, Grenoble, France
-#
-# Distributed under the terms of the GNU Lesser General Public License,
-# either version 3 of the License, or (at your option) any later version.
-# See LICENSE.txt for more info.
-# -----------------------------------------------------------------------------
-
-"""An IPython profile designed to provide a user friendly interface to Tango"""
-
-from __future__ import print_function
-
-__all__ = ["load_config", "load_ipython_extension", "unload_ipython_extension"]
-
-import sys
-import os
-import re
-import io
-import operator
-import textwrap
-
-from IPython.core.error import UsageError
-from IPython.utils.ipstruct import Struct
-from IPython.core.page import page
-from IPython.core.interactiveshell import InteractiveShell
-from IPython.config.application import Application
-from IPython.frontend.terminal.ipapp import launch_new_instance
-
-import PyTango
-import PyTango.utils
-
-_TG_EXCEPTIONS = PyTango.DevFailed, PyTango.ConnectionFailed, \
- PyTango.CommunicationFailed, \
- PyTango.NamedDevFailed, PyTango.NamedDevFailedList, \
- PyTango.WrongNameSyntax, PyTango.NonDbDevice, PyTango.WrongData, \
- PyTango.NonSupportedFeature, PyTango.AsynCall, \
- PyTango.AsynReplyNotArrived, PyTango.EventSystemFailed, \
- PyTango.DeviceUnlocked, PyTango.NotAllowed
-
-_DB_SYMB = "db"
-_DFT_TANGO_HOST = None
-_TANGO_STORE = "__tango_store"
-_TANGO_ERR = "__tango_error"
-_PYTHON_ERR = "__python_error"
-_tango_init = False
-
-#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
-# IPython utilities
-#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
-
-def get_pylab_mode():
- return get_app().pylab
-
-def get_color_mode():
- return get_config().InteractiveShell.colors
-
-def get_app():
- #return TerminalIPythonApp.instance()
- return Application.instance()
-
-def get_shell():
- """Get the global InteractiveShell instance."""
- return get_app().shell
-
-def get_ipapi():
- """Get the global InteractiveShell instance."""
- return InteractiveShell.instance()
-
-def get_config():
- return get_app().config
-
-def get_editor():
- return get_ipapi().editor
-
-def get_user_ns():
- return get_shell().user_ns
-
-class DeviceClassCompleter(object):
- """Completer class that returns the list of devices of some class when
- called. """
-
- def __init__(self, klass, devices):
- self._klass = klass
- self._devices = devices
-
- def __call__(self, ip, evt):
- return self._devices
-
-
-# Rewrite DeviceProxy constructor because the database context that the user is
-# using may be different than the default TANGO_HOST. What we do is always append
-# the name of the database in usage to the device name given by the user (in case
-# he doesn't give a database name him(her)self, of course.
-#__DeviceProxy_init_orig__ = PyTango.DeviceProxy.__init__
-#def __DeviceProxy__init__(self, dev_name):
-# db = __get_db()
-# if db is None: return
-# if dev_name.count(":") == 0:
-# db_name = "%s:%s" % (db.get_db_host(), db.get_db_port())
-# dev_name = "%s/%s" % (db_name, dev_name)
-# __DeviceProxy_init_orig__(self, dev_name)
-#PyTango.DeviceProxy.__init__ = __DeviceProxy__init__
-
-#-------------------------------------------------------------------------------
-# Completers
-#-------------------------------------------------------------------------------
-
-def __DeviceProxy_completer(ip, evt):
- db = __get_db()
- if db is None: return
- ret = list(db._db_cache.devices.keys())
- ret.extend(db._db_cache.aliases.keys())
- return ret
-
-def __DeviceClass_completer(ip, evt):
- db = __get_db()
- if db is None: return
- return list(db._db_cache.klasses.keys())
-
-def __DeviceAlias_completer(ip, evt):
- db = __get_db()
- if db is None: return
- return list(db._db_cache.aliases.keys())
-
-def __AttributeAlias_completer(ip, evt):
- db = __get_db()
- if db is None: return
- return list(db._db_cache.attr_aliases.keys())
-
-def __PureDeviceProxy_completer(ip, evt):
- db = __get_db()
- if db is None: return
- return list(db._db_cache.devices.keys())
-
-def __AttributeProxy_completer(ip, evt):
- db = __get_db()
- if db is None: return
- cache = db._db_cache
-
- symb = evt.symbol
- n = symb.count("/")
- ret, devs, dev_aliases = None, cache.devices, cache.aliases
- # dev_list and dev_alias_list are case insensitive. They should only be used
- # to search for elements. Their elements are the same as the keys of the
- # dictionaries devs and dev_aliases respectively
- dev_list, dev_alias_list = cache.device_list, cache.alias_list
- dev_name = None
- if n == 0:
- # means it can be an attr alias, a device name has alias or as full device name
- ret = list(cache.get("attr_aliases").keys())
- ret.extend([ d+"/" for d in devs ])
- ret.extend([ d+"/" for d in dev_aliases ])
- # device alias found!
- if symb in dev_alias_list:
- dev_name = symb
- elif n == 1:
- # it can still be a full device name
- ret = [ d+"/" for d in devs ]
- # it can also be devalias/attr_name
- dev, attr = symb.split("/")
- if dev in dev_alias_list:
- dev_name = dev
- elif n == 2:
- # it is for sure NOT an attribute alias or a device alias
- ret = [ d+"/" for d in devs ]
- # device found!
- if symb in dev_list:
- dev_name = symb
- elif n == 3:
- # it is for sure a full attribute name
- dev, sep, attr = symb.rpartition("/")
- if dev in dev_list:
- dev_name = dev
-
- if dev_name is None:
- return ret
-
- try:
- d = __get_device_proxy(dev_name)
- # first check in cache for the attribute list
- if not hasattr(d, "_attr_list"):
- d._attr_list = d.get_attribute_list()
- if ret is None:
- ret = []
- ret.extend([ "%s/%s" % (dev_name, a) for a in d._attr_list ])
- except:
- # either DeviceProxy could not be created or device is not online
- pass
-
- return ret
-
-def __get_device_proxy(dev_name):
- db = __get_db()
- if db is None: return
- cache = db._db_cache
- from_alias = cache.aliases.get(dev_name)
-
- if from_alias is not None:
- dev_name = from_alias
-
- data = cache.devices.get(dev_name)
- if data is not None:
- d = data[3]
- if d is None:
- try:
- d = data[3] = PyTango.DeviceProxy(dev_name)
- except:
- pass
- return d
-
-def __get_device_subscriptions(dev_name):
- db = __get_db()
- if db is None: return
- cache = db._db_cache
- from_alias = cache.aliases.get(dev_name)
-
- if from_alias is not None:
- dev_name = from_alias
-
- data = cache.devices.get(dev_name)
- if data is not None:
- return data[4]
-
-__monitor_completer = __AttributeProxy_completer
-
-#-------------------------------------------------------------------------------
-# Magic commands
-#-------------------------------------------------------------------------------
-
-def refreshdb(self, parameter_s=''):
- init_db(parameter_s)
-
-def switchdb(self, parameter_s=''):
- """Switches the active tango Database.
-
- Usage: switchdb <host>[(:| )<port>]
-
- <port> is optional. If not given it defaults to 10000.
-
- Examples:
- In [1]: switchdb homer:10005
- In [2]: switchdb homer 10005
- In [3]: switchdb homer"""
-
- if parameter_s == '':
- raise UsageError("%switchdb: Must specify a tango database name. "\
- "See '%switchdb?'")
- return init_db(parameter_s)
-
-def lsdev(self, parameter_s=''):
- """Lists all known tango devices.
-
- Usage: lsdev [<device name filter(regular expression)]
-
- Examples:
- In [1]: lsdev
- In [2]: lsdev sys.*"""
-
- if parameter_s:
- reg_exp = re.compile(parameter_s, re.IGNORECASE)
- else:
- reg_exp = None
-
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database. Device list is empty")
- return
- data = db._db_cache.devices
-
- s = io.StringIO()
- lengths = 40, 25, 25, 20
- title = "Device", "Alias", "Server", "Class"
- templ = "{0:{l[0]}} {1:{l[1]}} {2:{l[2]}} {3:{l[3]}}"
- msg = templ.format(*title, l=lengths)
- print(msg, file=s)
- print(*map(operator.mul, lengths, len(lengths)*"-"), file=s)
- for d, v in data.items():
- if reg_exp and not reg_exp.match(d):
- continue
- print(templ.format(d, v[0], v[1], v[2], l=lengths), file=s)
- s.seek(0)
- page(s.read())
-
-def lsdevclass(self, parameter_s=''):
- """Lists all known tango device classes.
-
- Usage: lsdevclass [<class name filter(regular expression)]
-
- Examples:
- In [1]: lsdevclass
- In [2]: lsdevclass Motor.*"""
-
- if parameter_s:
- reg_exp = re.compile(parameter_s, re.IGNORECASE)
- else:
- reg_exp = None
-
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database. Device class list is empty")
- return
- data = db._db_cache.klasses
-
- data = [ "%-030s" % klass for klass in data.keys() if not reg_exp or reg_exp.match(klass) ]
- s = textwrap.fill(" ".join(data), 80)
- page(s)
-
-def lsserv(self, parameter_s=''):
- """Lists all known tango servers.
-
- Usage: lsserv [<class name filter(regular expression)]
-
- Examples:
- In [1]: lsserv
- In [2]: lsserv Motor/.*"""
-
- if parameter_s:
- reg_exp = re.compile(parameter_s, re.IGNORECASE)
- else:
- reg_exp = None
-
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database. Device class list is empty")
- return
- data = db._db_cache.servers
-
- data = [ "%-030s" % server for server in data.keys() if not reg_exp or reg_exp.match(server) ]
- s = textwrap.fill(" ".join(data), 80)
- page(s)
-
-def tango_error(self, parameter_s=''):
- """Displays detailed information about the last tango error"""
- global _TANGO_ERR
- err_info = get_user_ns().get(_TANGO_ERR)
- if err_info is None:
- print("No tango error reported so far.")
- return
- print("Last tango error:")
- print(err_info[1])
-
-def python_error(self, parameter_s=''):
- """Displays detailed information about the last python error"""
- global _PYTHON_ERR
- err_info = get_user_ns().get(_PYTHON_ERR)
- if err_info is None:
- print("No error reported so far.")
- return
- ip = get_ipapi()
- etype, evalue, etb = err_info[:3]
- ip.InteractiveTB(etype=etype, evalue=evalue, etb=etb, tb_offset=None)
-
-_EVT_LOG = None
-def __get_event_log():
- global _EVT_LOG
- if _EVT_LOG is None:
-# qthreads = get_config().q4thread
-# if qthreads:
-# import ipy_qt
-# model = ipy_qt.EventLoggerTableModel(capacity=10000)
-# _EVT_LOG = ipy_qt.EventLogger(model=model)
-# _EVT_LOG.setWindowTitle("ITango - Event Logger Table")
-# else:
- import PyTango.ipython.eventlogger
- _EVT_LOG = PyTango.ipython.eventlogger.EventLogger(capacity=10000, pager=page)
- return _EVT_LOG
-
-def mon(self, parameter_s=''):
- """Monitor a given attribute.
-
- %mon -a <attribute name> - activates monitoring of given attribute
- %mon -d <attribute name> - deactivates monitoring of given attribute
- %mon -r - deactivates monitoring of all attributes
- %mon -i <id> - displays detailed information for the event with given id
- %mon -l <dev filter> <attr filter> - shows event table filtered with the regular expression for attribute name
- %mon - shows event table (= %mon -i .* .*)"""
-
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
-
- # make sure parameter_s is a str and not a unicode
- parameter_s = str(parameter_s)
- opts, args = self.parse_options(parameter_s,'adril', mode='list')
- if len(args) > 3:
- raise UsageError("%mon: too many arguments")
- if 'd' in opts:
- try:
- todel = args[0]
- except IndexError:
- raise UsageError("%mon -d: must provide an attribute to unmonitor")
- else:
- try:
- dev, sep, attr = todel.rpartition("/")
- subscriptions = __get_device_subscriptions(dev)
- id = subscriptions[attr.lower()]
- del subscriptions[attr.lower()]
- d = __get_device_proxy(dev)
- d.unsubscribe_event(id)
- print("Stopped monitoring '%s'" % todel)
- except KeyError:
- raise UsageError("%%mon -d: Not monitoring '%s'" % todel)
-
- elif 'a' in opts:
- try:
- toadd = args[0]
- except IndexError:
- raise UsageError("%mon -a: must provide an attribute to monitor")
- dev, sep, attr = toadd.rpartition("/")
- subscriptions = __get_device_subscriptions(dev)
- id = subscriptions.get(attr.lower())
- if id is not None:
- raise UsageError("%%mon -a: Already monitoring '%s'" % toadd)
- d = __get_device_proxy(dev)
- w = __get_event_log()
- model = w.model()
- id = d.subscribe_event(attr, PyTango.EventType.CHANGE_EVENT, model, [])
- subscriptions[attr.lower()] = id
- print("'%s' is now being monitored. Type 'mon' to see all events" % toadd)
- elif 'r' in opts:
- for d, v in db._db_cache.devices.items():
- d, subs = v[3], v[4]
- for id in subs.values():
- d.unsubscribe_event(id)
- v[4] = {}
- elif 'i' in opts:
- try:
- evtid = int(args[0])
- except IndexError:
- raise UsageError("%mon -i: must provide an event ID")
- except ValueError:
- raise UsageError("%mon -i: must provide a valid event ID")
- try:
- w = __get_event_log()
- e = w.getEvents()[evtid]
- if e.err:
- print(str(PyTango.DevFailed(*e.errors)))
- else:
- print(str(e))
- except IndexError:
- raise UsageError("%mon -i: must provide a valid event ID")
- elif 'l' in opts:
- try:
- dexpr = args[0]
- aexpr = args[1]
- except IndexError:
- raise UsageError("%mon -l: must provide valid device and " \
- "attribute filters")
- w = __get_event_log()
- w.show(dexpr, aexpr)
- else:
- w = __get_event_log()
- w.show()
-
-#-------------------------------------------------------------------------------
-# Useful functions (not magic commands but accessible from CLI as normal python
-# functions)
-#-------------------------------------------------------------------------------
-
-def get_device_map():
- """Returns a dictionary where keys are device names and value is a sequence
- of 4 elements:
- - alias name (empty string if no alias is defined)
- - tango server name (full tango server name <name>/<instance>)
- - tango class name
- - DeviceProxy to the device or None if it hasn't been initialized yet
- (this last element is for internal tango usage only. If you need a
- DeviceProxy to this device, create your own)"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.devices
-
-def get_server_map():
- """Returns a dictionary where keys are server names (<name>/<instance>)
- and value is a sequence of device names that belong to the server"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.servers
-
-def get_class_map():
- """Returns a dictionary where keys are the tango classes and value is a
- sequence of device names that belong to the tango class"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.klasses
-
-def get_alias_map():
- """Returns a dictionary where keys are the tango device aliases and value
- is a the tango device name"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.aliases
-
-def get_device_list():
- """Returns a case insensitive list of device names for the current
- database"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.device_list
-
-def get_alias_list():
- """Returns a case insensitive list of device aliases for the current
- database"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.alias_list
-
-#-------------------------------------------------------------------------------
-# Private helper methods
-#-------------------------------------------------------------------------------
-
-def __exc_handler(ip, etype, value, tb, tb_offset=None):
- global _TG_EXCEPTIONS
- user_ns = get_user_ns()
- if etype in _TG_EXCEPTIONS:
- global _TANGO_ERR
- user_ns[_TANGO_ERR] = etype, value, tb, tb_offset
- if len(value.args):
- v = value.args[0]
- print("%s: %s" % (v.reason ,v.desc))
- else:
- print("Empty DevFailed")
- print("(For more detailed information type: tango_error)")
- else:
- global _PYTHON_ERR
- user_ns[_PYTHON_ERR] = etype, value, tb, tb_offset
- print(etype.__name__ + ": " + str(value))
- print("(For more detailed information type: python_error)")
-
-def __get_default_tango_host():
- global _DFT_TANGO_HOST
- if _DFT_TANGO_HOST is None:
- try:
- db = PyTango.Database()
- _DFT_TANGO_HOST = "%s:%s" % (db.get_db_host(), db.get_db_port())
- except:
- pass
- return _DFT_TANGO_HOST
-
-def __get_db(host_port=None):
- """host_port == None: Use current DB whatever it is or create
- default if doesn't exist
- host_port == '' : use default db. If it is not the current db, switch
- current db to it and return it
- host_port == ... : if ... is not the current db, switch current db to it
- and return it
- """
-
- ip = get_ipapi()
- user_ns = get_user_ns()
-
- global _DB_SYMB
- db = user_ns.get(_DB_SYMB)
-
- if host_port is None:
- if db is None:
- host_port = __get_default_tango_host()
- elif host_port == '':
- host_port = __get_default_tango_host()
- else:
- host_port = host_port.strip().replace(" ",":")
- if host_port.count(":") == 0:
- host_port += ":10000"
-
- if host_port is not None:
- host_port = str(host_port)
-
- if db is None:
- create_db = True
- elif host_port is None:
- create_db = False
- else:
- old_host_port = "%s:%s" % (db.get_db_host(), db.get_db_port())
- create_db = old_host_port != host_port
-
- if create_db:
- try:
- db = PyTango.Database(*host_port.split(":"))
-
- user_ns["DB_NAME"] = host_port
- except Exception as e:
- if db:
- print("\nCould not access Database %s:" % host_port)
- print(str(e))
- old_host_port = "%s:%s" % (db.get_db_host(), db.get_db_port())
- print("Maintaining connection to Database", old_host_port)
- user_ns["DB_NAME"] = old_host_port
- else:
- print("\nCould not access any Database. Make sure:")
- print("\t- .tangorc, /etc/tangorc or TANGO_HOST environment is defined.")
- print("\t- the Database DS is running")
- user_ns["DB_NAME"] = "OFFLINE"
-
- # register the 'db' in the user namespace
- user_ns.update({ _DB_SYMB : db })
-
- return db
-
-def __get_obj_name(o):
- try:
- n = o.__name__
- except:
- try:
- n = o.__class__.__name__
- except:
- n = "<unknown>"
- return n
-
-def __completer_wrapper(f):
- def wrapper(ip, evt):
- try:
- return f(ip, evt)
- except Exception as e:
- print()
- print("An unexpected exception ocorred during ITango command completer.")
- print("Please send a bug report to the PyTango team with the following information:")
- print(80*"-")
- print("Completer:",__get_obj_name(f))
- print(80*"-")
- import traceback
- traceback.print_exc()
- print(80*"-")
- raise e
- return wrapper
-
-def __expose_magic(ip, name, fn, completer_func=None):
- ip.define_magic(name, fn)
-
- if completer_func is None:
- return
-
- # enable macro param completion
- ip.set_hook('complete_command', completer_func, re_key = ".*" + name)
-
-def __unexpose_magic(ip, name):
- delattr(ip, name)
-
-def __build_color_scheme(ip, name):
- import IPython.Prompts
- import IPython.PyColorize
- import IPython.excolors
- from IPython.utils.coloransi import TermColors, InputTermColors
-
- # make some schemes as instances so we can copy them for modification easily:
- PromptColors = IPython.Prompts.PromptColors
- ANSICodeColors = IPython.PyColorize.ANSICodeColors
- ExceptionColors = IPython.excolors.ExceptionColors
- TBColors = ip.IP.InteractiveTB.color_scheme_table
- SyntaxColors = ip.IP.SyntaxTB.color_scheme_table
- InspectColors = IPython.OInspect.InspectColors
-
- promptTangoColors = PromptColors['Linux'].copy(name)
- ANSITangoColors = ANSICodeColors['Linux'].copy(name)
- exceptionTangoColors = ExceptionColors['Linux'].copy(name)
- TBTangoColors = TBColors['Linux'].copy(name)
- syntaxTangoColors = SyntaxColors['Linux'].copy(name)
- inspectTangoColors = InspectColors['Linux'].copy(name)
-
- # initialize prompt with default tango colors
- promptTangoColors.colors.in_prompt = InputTermColors.Purple
- promptTangoColors.colors.in_number = InputTermColors.LightPurple
- promptTangoColors.colors.in_prompt2 = InputTermColors.Purple
- promptTangoColors.colors.out_prompt = TermColors.Blue
- promptTangoColors.colors.out_number = TermColors.LightBlue
-
- ret= { "prompt" : (PromptColors, promptTangoColors),
- "ANSI" : (ANSICodeColors, ANSITangoColors),
- "except" : (ExceptionColors, exceptionTangoColors),
- "TB" : (TBColors, TBTangoColors),
- "Syntax" : (SyntaxColors, syntaxTangoColors),
- "Inspect": (InspectColors, inspectTangoColors) }
-
- if ip.IP.isthreaded:
- TBThreadedColors = ip.IP.sys_excepthook.color_scheme_table
- TBThreadedTangoColors = TBThreadedColors['Linux'].copy(name)
- ret["TBThreaded"] = TBThreadedColors, TBThreadedTangoColors
- return ret
-
-#-------------------------------------------------------------------------------
-# Initialization methods
-#-------------------------------------------------------------------------------
-
-def init_pytango(ip):
- """Initializes the IPython environment with PyTango elements"""
-
- # export symbols to IPython namepspace
- ip.ex("import PyTango")
- ip.ex("from PyTango import DeviceProxy, AttributeProxy, Database, Group")
- ip.ex("Device = DeviceProxy")
- ip.ex("Attribute = AttributeProxy")
-
- # add completers
- dp_completer = __completer_wrapper(__DeviceProxy_completer)
- attr_completer = __completer_wrapper(__AttributeProxy_completer)
- ip.set_hook('complete_command', dp_completer, re_key = ".*DeviceProxy[^\w\.]+")
- ip.set_hook('complete_command', dp_completer, re_key = ".*Device[^\w\.]+")
- ip.set_hook('complete_command', attr_completer, re_key = ".*AttributeProxy[^\w\.]+")
- ip.set_hook('complete_command', attr_completer, re_key = ".*Attribute[^\w\.]+")
-
- ip.set_custom_exc((Exception,), __exc_handler)
-
-def init_db(parameter_s=''):
- ip = get_ipapi()
- user_ns = get_user_ns()
- global _DB_SYMB
- old_db = user_ns.get(_DB_SYMB)
-
- db = __get_db(parameter_s)
-
- if old_db is not None and hasattr(old_db, "_db_cache"):
- old_junk = old_db._db_cache["junk"].keys()
- for e in old_junk:
- del user_ns[e]
- else:
- old_junk = ()
-
- if db is None: return
-
- os.environ["TANGO_HOST"] = "%s:%s" % (db.get_db_host(), db.get_db_port())
-
- # Initialize device and server information
- query = "SELECT name, alias, server, class FROM device order by name"
-
- r = db.command_inout("DbMySqlSelect", query)
- row_nb, column_nb = r[0][-2], r[0][-1]
- results, data = r[0][:-2], r[1]
- assert row_nb == len(data) / column_nb
- devices, aliases, servers, klasses = data[0::4], data[1::4], data[2::4], data[3::4]
-
- #CD = PyTango.utils.CaselessDict
- CD = dict
- dev_dict, serv_dict, klass_dict, alias_dict = CD(), CD(), CD(), CD()
-
- for device, alias, server, klass in zip(devices, aliases, servers, klasses):
- dev_lower = device.lower()
-
- # hide dserver devices
- if dev_lower.startswith("dserver/"): continue
-
- # hide alias that start with "_"
- if alias and alias[0] == "_": alias = ''
-
- # last None below is to be filled by DeviceProxy object on demand
- # last empty dict<str, int> where keys is attribute name and value is
- # the subscription id
- dev_dict[device] = [alias, server, klass, None, {}]
- serv_devs = serv_dict.get(server)
- if serv_devs is None:
- serv_dict[server] = serv_devs = []
- serv_devs.append(device)
- klass_devs = klass_dict.get(klass)
- if klass_devs is None:
- klass_dict[klass] = klass_devs = []
- klass_devs.append(device)
- if len(alias):
- alias_dict[alias] = device
- serv_devs.append(alias)
- klass_devs.append(alias)
-
- exposed_klasses = {}
- excluded_klasses = "DServer",
- for klass, devices in klass_dict.items():
- if klass in excluded_klasses:
- continue
- exists = klass in user_ns
- if not exists or klass in old_junk:
- c = DeviceClassCompleter(klass, devices)
- ip.set_hook('complete_command', c, re_key = ".*" + klass + "[^\w\.]+")
- exposed_klasses[klass] = PyTango.DeviceProxy
-
- # expose classes no user namespace
- user_ns.update(exposed_klasses)
-
- # Initialize attribute information
- query = "SELECT name, alias FROM attribute_alias order by alias"
-
- r = db.command_inout("DbMySqlSelect", query)
- row_nb, column_nb = r[0][-2], r[0][-1]
- results, data = r[0][:-2], r[1]
- assert row_nb == len(data) / column_nb
- attributes, aliases = data[0::2], data[1::2]
-
- attr_alias_dict = {}
- for attribute, alias in zip(attributes, aliases):
- if len(alias):
- attr_alias_dict[alias] = attribute
-
- device_list = PyTango.utils.CaselessList(dev_dict.keys())
- alias_list = PyTango.utils.CaselessList(alias_dict.keys())
- attr_alias_list = PyTango.utils.CaselessList(attr_alias_dict.keys())
-
- # Build cache
- db_cache = Struct(devices=dev_dict, aliases=alias_dict,
- servers=serv_dict, klasses=klass_dict, junk=exposed_klasses,
- attr_aliases=attr_alias_dict, device_list=device_list,
- alias_list=alias_list, attr_alias_list=attr_alias_list)
-
- db._db_cache = db_cache
-
- # Add this DB to the list of known DBs (for possible use in magic commands)
- if db.get_db_port_num() == 10000:
- db_name = db.get_db_host()
- else:
- db_name = "%s:%s" % (db.get_db_host(), db.get_db_port())
- return db
-
-def init_magic(ip):
-
- import IPython.core.magic
-
- new_style_magics = hasattr(IPython.core.magic, 'Magics') and hasattr(IPython.core.magic, 'magics_class')
-
- if new_style_magics:
- @IPython.core.magic.magics_class
- class Tango(IPython.core.magic.Magics):
-
- refreshdb = IPython.core.magic.line_magic(refreshdb)
- switchdb = IPython.core.magic.line_magic(switchdb)
- lsdev = IPython.core.magic.line_magic(lsdev)
- lsdevclass = IPython.core.magic.line_magic(lsdevclass)
- lsserv = IPython.core.magic.line_magic(lsserv)
- tango_error = IPython.core.magic.line_magic(tango_error)
- python_error = IPython.core.magic.line_magic(python_error)
- mon = IPython.core.magic.line_magic(mon)
-
- ip.register_magics(Tango)
- ip.set_hook('complete_command', __monitor_completer, re_key = ".*" + "mon")
- else:
- __expose_magic(ip, "refreshdb", refreshdb)
- __expose_magic(ip, "switchdb", switchdb)
- __expose_magic(ip, "lsdev", lsdev)
- __expose_magic(ip, "lsdevclass", lsdevclass)
- __expose_magic(ip, "lsserv", lsserv)
- __expose_magic(ip, "tango_error", tango_error)
- __expose_magic(ip, "python_error", python_error)
- __expose_magic(ip, "mon", mon, __monitor_completer)
-
- get_user_ns().update({"get_device_map" : get_device_map,
- "get_server_map" : get_server_map,
- "get_class_map" : get_class_map,
- "get_alias_map" : get_alias_map,
- "get_device_list" : get_device_list,
- "get_alias_list" : get_alias_list})
-
-def complete(text):
- """a super complete!!!!"""
- self = get_ipapi().IP
- complete = self.Completer.complete
- state = 0
- comps = set()
- while True:
- newcomp = complete("", state, line_buffer=text)
- if newcomp is None:
- break
- comps.add(newcomp)
- state += 1
- outcomps = sorted(comps)
- return outcomps
-
-__DIRNAME = os.path.dirname(os.path.abspath(__file__))
-__RES_DIR = os.path.join(__DIRNAME, os.path.pardir, 'resource')
-
-class __TangoInfo(object):
- """Helper class for when DeviceProxy.info() is not available"""
-
- def __init__(self, dev):
- try:
- db = dev.get_device_db()
- klass = db.get_class_for_device(dev.dev_name())
- self.dev_class = self.dev_type = klass
- except:
- self.dev_class = self.dev_type = 'Device'
- self.doc_url = 'http://www.esrf.eu/computing/cs/tango/tango_doc/ds_doc/index.html'
- self.server_host = 'Unknown'
- self.server_id = 'Unknown'
- self.server_version = 1
-
-def __get_device_icon(dev_proxy, klass="Device"):
- icon_prop = "__icon"
- db = dev_proxy.get_device_db()
- try:
- icon_filename = dev_proxy.get_property(icon_prop)[icon_prop]
- if icon_filename:
- icon_filename = icon_filename[0]
- else:
- icon_filename = db.get_class_property(klass, icon_prop)[icon_prop]
- if icon_filename:
- icon_filename = icon_filename[0]
- else:
- icon_filename = klass.lower() + os.path.extsep + "png"
- except:
- icon_filename = klass.lower() + os.path.extsep + "png"
-
- if os.path.isabs(icon_filename):
- icon = icon_filename
- else:
- icon = os.path.join(__RES_DIR, icon_filename)
- if not os.path.isfile(icon):
- icon = os.path.join(__RES_DIR, "device.png")
- return icon
-
-__DEV_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td width="140" rowspan="7" valign="middle" align="center"><img src="{icon}" height="128"/></td>
- <td width="140">Name:</td><td><b>{name}</b></td></tr>
-<tr><td width="140">Alias:</td><td>{alias}</td></tr>
-<tr><td width="140">Database:</td><td>{database}</td></tr>
-<tr><td width="140">Type:</td><td>{dev_class}</td></tr>
-<tr><td width="140">Server:</td><td>{server_id}</td></tr>
-<tr><td width="140">Server host:</td><td>{server_host}</td></tr>
-<tr><td width="140">Documentation:</td><td><a target="_blank" href="{doc_url}">{doc_url}</a></td></tr>
-</table>"""
-
-def display_deviceproxy_html(dev_proxy):
- """displayhook function for PyTango.DeviceProxy, rendered as HTML"""
- try:
- info = dev_proxy.info()
- except:
- info = __TangoInfo(dev_proxy)
- name = dev_proxy.dev_name()
- fmt = dict(dev_class=info.dev_class, server_id=info.server_id,
- server_host=info.server_host, name=name)
-
- try:
- fmt["alias"] = dev_proxy.alias()
- except:
- fmt["alias"] = "-----"
-
- db = dev_proxy.get_device_db()
- try:
- fmt["database"] = db.get_db_host() + ":" + db.get_db_port()
- except:
- try:
- fmt["database"] = db.get_file_name()
- except:
- fmt["database"] = "Unknown"
-
- doc_url = info.doc_url.split("\n")[0]
- try:
- fmt["doc_url"] = doc_url[doc_url.index("http"):]
- except ValueError:
- fmt["doc_url"] = doc_url
-
- fmt['icon'] = __get_device_icon(dev_proxy, info.dev_class)
-
- return __DEV_HTML_TEMPLATE.format(**fmt)
-
-__DB_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td width="140" rowspan="2" valign="middle" align="center"><img src="{icon}" height="128"/></td>
- <td><b>{name}</b></td></tr>
-<tr><td>{info}</td></tr>
-</table>"""
-
-def display_database_html(db):
- """displayhook function for PyTango.Database, rendered as HTML"""
- fmt = dict()
-
- try:
- fmt["name"] = db.get_db_host() + ":" + db.get_db_port()
- except:
- try:
- fmt["name"] = db.get_file_name()
- except:
- fmt["name"] = "Unknown"
-
- try:
- fmt["info"] = db.get_info().replace("\n", "<BR/>")
- except:
- fmt["info"] = "Unknown"
-
- fmt['icon'] = os.path.join(__RES_DIR, "database.png")
-
- return __DB_HTML_TEMPLATE.format(**fmt)
-
-__DEV_ATTR_RW_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td colspan="2" bgcolor="{bgcolor}">{name} ({type}, {data_format}, {quality}) at {time}</td></tr>
-<tr><td bgcolor="#EEEEEE" width="140">value{r_dim}:</td>
- <td bgcolor="#EEEEEE">{value}</td></tr>
-<tr><td bgcolor="#EEEEEE" width="140">w_value{w_dim}:</td>
- <td bgcolor="#EEEEEE">{w_value}</td></tr>
-</table>"""
-
-__DEV_ATTR_RO_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td colspan="2" bgcolor="{bgcolor}">{name} ({type}, {data_format}, {quality}) at {time}</td></tr>
-<tr><td bgcolor="#EEEEEE" width="140">value{r_dim}:</td>
- <td bgcolor="#EEEEEE">{value}</td></tr>
-</table>"""
-
-__DEV_ATTR_ERR_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td bgcolor="#FF0000">{name} ({type}, {data_format}, {quality}) at {time}</td></tr>
-<tr><td bgcolor="#EEEEEE">{error}</td></tr>
-</table>"""
-
-QUALITY_TO_HEXCOLOR_STR = {
- PyTango.AttrQuality.ATTR_VALID : ("#00FF00", "#000000"),
- PyTango.AttrQuality.ATTR_INVALID : ("#808080", "#FFFFFF"),
- PyTango.AttrQuality.ATTR_ALARM : ("#FF8C00", "#FFFFFF"),
- PyTango.AttrQuality.ATTR_WARNING : ("#FF8C00", "#FFFFFF"),
- PyTango.AttrQuality.ATTR_CHANGING : ("#80A0FF", "#000000"),
- None : ("#808080", "#000000"),
-}
-
-def display_deviceattribute_html(da):
- """displayhook function for PyTango.DeviceAttribute, rendered as HTML"""
- fmt = dict(name=da.name, type=da.type, data_format=da.data_format)
- template = None
- if da.has_failed:
- fmt['error'] = "\n".join(map(str, da.get_err_stack())).replace("\n", "<br/>")
-
- template = __DEV_ATTR_ERR_HTML_TEMPLATE
- else:
- rd, wd = da.r_dimension, da.w_dimension
- if wd.dim_x == 0 and wd.dim_y == 0 and da.w_value is None:
- template = __DEV_ATTR_RO_HTML_TEMPLATE
- else:
- template = __DEV_ATTR_RW_HTML_TEMPLATE
- fmt['w_value'] = str(da.w_value)
- if da.data_format == PyTango.AttrDataFormat.SCALAR:
- fmt['w_dim'] = ""
- else:
- fmt['w_dim'] = "<br/>(%d, %d)" % (wd.dim_x, wd.dim_y)
- fmt['bgcolor'], fmt['fgcolor'] = QUALITY_TO_HEXCOLOR_STR[da.quality]
- fmt['quality'] = str(da.quality)
- if da.data_format == PyTango.AttrDataFormat.SCALAR:
- fmt['r_dim'] = ""
- else:
- fmt['r_dim'] = "<br/>(%d, %d)" % (rd.dim_x, rd.dim_y)
- fmt['value'] = str(da.value)
- fmt['time'] = str(da.time.todatetime())
- return template.format(**fmt)
-
-__GROUP_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td width="100" bgcolor="#EEEEEE">Name:</td><td bgcolor="#EEEEEE">{name}</td></tr>
-<tr><td width="100" bgcolor="#EEEEEE">Size:</td><td bgcolor="#EEEEEE">{size}</td></tr>
-<tr><td width="100" bgcolor="#EEEEEE">Devices:</td><td bgcolor="#EEEEEE">{devices}</td></tr>
-</table>"""
-
-def display_group_html(group):
- devices = group.get_device_list()
- devices = ", ".join(devices)
- fmt=dict(name=group.get_name(), size=group.get_size(), devices=devices)
- return __GROUP_HTML_TEMPLATE.format(**fmt)
-
-__GROUP_REPLY_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td bgcolor="#EEEEEE">{name}</td></tr>
-<tr><td>{data}</td></tr>
-"""
-
-__GROUP_REPLY_ERR_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td bgcolor="#FF0000">{name}</td></tr>
-<tr><td bgcolor="#EEEEEE">{error}</td></tr>
-</table>"""
-
-def display_groupreply_html(gr):
- fmt = dict(name="%s/%s" % (gr.dev_name(), gr.obj_name()))
- template = None
- if gr.has_failed():
- fmt['error'] = "\n".join(map(str, gr.get_err_stack())).replace("\n", "<br/>")
- template = __GROUP_REPLY_ERR_HTML_TEMPLATE
- else:
- template = __GROUP_REPLY_HTML_TEMPLATE
- data = gr.get_data()
- if isinstance(data, PyTango.DeviceAttribute):
- data = display_deviceattribute_html(data)
- fmt["data"] = data
-
- ret = template.format(**fmt)
- return ret
-
-def init_display(ip):
- html_formatter = ip.display_formatter.formatters["text/html"]
- html_formatter.for_type(PyTango.DeviceProxy, display_deviceproxy_html)
- html_formatter.for_type(PyTango.Database, display_database_html)
- html_formatter.for_type(PyTango.DeviceAttribute, display_deviceattribute_html)
- html_formatter.for_type(PyTango.Group, display_group_html)
- html_formatter.for_type(PyTango.GroupAttrReply, display_groupreply_html)
- html_formatter.for_type(PyTango.GroupCmdReply, display_groupreply_html)
-
-
-def init_ipython(ip=None, store=True, pytango=True, colors=True, console=True,
- magic=True):
-
- if ip is None:
- ip = get_ipapi()
-
- global _tango_init
- if _tango_init is True: return
-
- init_display(ip)
-
- if pytango:
- init_pytango(ip)
-
- init_db()
-
- if magic:
- init_magic(ip)
-
- _tango_init = True
-
-def load_config(config):
- import PyTango.ipython
- import IPython.utils.coloransi
-
- d = { "version" : str(PyTango.ipython.get_pytango_version()),
- "pyver" : str(PyTango.ipython.get_python_version()),
- "ipyver" : str(PyTango.ipython.get_ipython_version()),
- "pytangover" : str(PyTango.ipython.get_pytango_version()), }
- d.update(IPython.utils.coloransi.TermColors.__dict__)
-
- so = Struct(
- tango_banner="""%(Blue)shint: Try typing: mydev = Device("%(LightBlue)s<tab>%(Normal)s\n""")
-
- so = config.get("tango_options", so)
-
- ipy_ver = PyTango.ipython.get_ipython_version()
-
- # ------------------------------------
- # Application
- # ------------------------------------
- app = config.Application
- app.log_level = 30
-
- # ------------------------------------
- # InteractiveShell
- # ------------------------------------
- i_shell = config.InteractiveShell
- i_shell.colors = 'Linux'
-
- if ipy_ver >= "0.12":
- # ------------------------------------
- # PromptManager (ipython >= 0.12)
- # ------------------------------------
- prompt = config.PromptManager
- prompt.in_template = 'ITango [\\#]: '
- prompt.out_template = 'Result [\\#]: '
- else:
- # (Deprecated in ipython >= 0.12 use PromptManager.in_template)
- i_shell.prompt_in1 = 'ITango [\\#]: '
- # (Deprecated in ipython >= 0.12 use PromptManager.out_template)
- i_shell.prompt_out = 'Result [\\#]: '
-
- # ------------------------------------
- # InteractiveShellApp
- # ------------------------------------
- i_shell_app = config.InteractiveShellApp
- extensions = getattr(i_shell_app, 'extensions', [])
- extensions.append('PyTango.ipython')
- i_shell_app.extensions = extensions
-
- # ------------------------------------
- # TerminalIPythonApp: options for the IPython terminal (and not Qt Console)
- # ------------------------------------
- term_app = config.TerminalIPythonApp
- term_app.display_banner = True
- #term_app.nosep = False
- #term_app.classic = True
-
- # ------------------------------------
- # IPKernelApp: options for the Qt Console
- # ------------------------------------
- #kernel_app = config.IPKernelApp
- ipython_widget = config.IPythonWidget
- ipython_widget.in_prompt = 'ITango [<span class="in-prompt-number">%i</span>]: '
- ipython_widget.out_prompt = 'Result [<span class="out-prompt-number">%i</span>]: '
-
- #zmq_i_shell = config.ZMQInteractiveShell
-
- # ------------------------------------
- # TerminalInteractiveShell
- # ------------------------------------
- term_i_shell = config.TerminalInteractiveShell
- banner = """\
-%(Purple)sITango %(version)s%(Normal)s -- An interactive %(Purple)sTango%(Normal)s client.
-
-Running on top of Python %(pyver)s, IPython %(ipyver)s and PyTango %(pytangover)s
-
-help -> ITango's help system.
-object? -> Details about 'object'. ?object also works, ?? prints more.
-"""
-
- banner = banner % d
- banner = banner.format(**d)
- tango_banner = so.tango_banner % d
- tango_banner = tango_banner.format(**d)
- all_banner = "\n".join((banner, tango_banner))
-
- term_i_shell.banner1 = banner
- term_i_shell.banner2 = tango_banner
-
- # ------------------------------------
- # FrontendWidget
- # ------------------------------------
- frontend_widget = config.ITangoConsole
- frontend_widget.banner = all_banner
-
-def load_ipython_extension(ipython):
- # The ``ipython`` argument is the currently active
- # :class:`InteractiveShell` instance that can be used in any way.
- # This allows you do to things like register new magics, plugins or
- # aliases.
- init_ipython(ip=ipython, store=False, colors=False)
-
-def unload_ipython_extension(ipython):
- # If you want your extension to be unloadable, put that logic here.
- #print "Unloading PyTango IPython extension"
- pass
-
-def run():
-
- # overwrite the original IPython Qt widget with our own so we can put a
- # customized banner. IPython may have been installed without Qt support so we
- # protect this code against an import error
- try:
- from IPython.utils.traitlets import Unicode
- from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
-
- class ITangoConsole(RichIPythonWidget):
-
- banner = Unicode(config=True)
-
- def _banner_default(self):
- config = get_config()
- return config.ITangoConsole.banner
-
- import IPython.frontend.qt.console.qtconsoleapp
- IPythonQtConsoleApp = IPython.frontend.qt.console.qtconsoleapp.IPythonQtConsoleApp
- IPythonQtConsoleApp.widget_factory = ITangoConsole
- except ImportError:
- pass
-
- argv = sys.argv
-
- try:
- for i, arg in enumerate(argv[:1]):
- if arg.startswith('--profile='):
- break
- else:
- argv.append("--profile=tango")
- except:
- pass
-
- launch_new_instance()
-
diff --git a/src/boost/python/ipython/ipython_10_00/__init__.py b/src/boost/python/ipython/ipython_10_00/__init__.py
deleted file mode 100644
index 587afd6..0000000
--- a/src/boost/python/ipython/ipython_10_00/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# -----------------------------------------------------------------------------
-# This file is part of PyTango (http://www.tinyurl.com/PyTango)
-#
-# Copyright 2006-2012 CELLS / ALBA Synchrotron, Bellaterra, Spain
-# Copyright 2013-2014 European Synchrotron Radiation Facility, Grenoble, France
-#
-# Distributed under the terms of the GNU Lesser General Public License,
-# either version 3 of the License, or (at your option) any later version.
-# See LICENSE.txt for more info.
-# -----------------------------------------------------------------------------
-
-__all__ = ['load_ipython_extension', 'unload_ipython_extension', 'load_config',
- 'run', 'install', 'is_installed']
-
-from .ipython_10_00 import load_ipython_extension, unload_ipython_extension, \
- load_config, run
-from .ipy_install import install, is_installed
-
diff --git a/src/boost/python/ipython/ipython_10_00/ipy_install.py b/src/boost/python/ipython/ipython_10_00/ipy_install.py
deleted file mode 100644
index da5933c..0000000
--- a/src/boost/python/ipython/ipython_10_00/ipy_install.py
+++ /dev/null
@@ -1,109 +0,0 @@
-#!/usr/bin/env python
-
-# -----------------------------------------------------------------------------
-# This file is part of PyTango (http://www.tinyurl.com/PyTango)
-#
-# Copyright 2006-2012 CELLS / ALBA Synchrotron, Bellaterra, Spain
-# Copyright 2013-2014 European Synchrotron Radiation Facility, Grenoble, France
-#
-# Distributed under the terms of the GNU Lesser General Public License,
-# either version 3 of the License, or (at your option) any later version.
-# See LICENSE.txt for more info.
-# -----------------------------------------------------------------------------
-
-from __future__ import with_statement
-
-import os
-import sys
-
-import IPython
-from IPython.core.profiledir import ProfileDirError, ProfileDir
-from IPython.core.application import BaseIPythonApplication
-from IPython.utils.io import ask_yes_no
-
-try:
- from IPython.paths import get_ipython_dir
-except ImportError:
- try:
- from IPython.utils.path import get_ipython_dir
- except ImportError:
- from IPython.genutils import get_ipython_dir
-
-import PyTango
-
-
-__PROFILE = """\
-#!/usr/bin/env ipython
-\"\"\"An automaticaly generated IPython profile designed to provide a user
-friendly interface to Tango.
-Created with PyTango {pytangover} for IPython {ipyver}\"\"\"
-
-import PyTango.ipython
-
-config = get_config()
-PyTango.ipython.load_config(config)
-
-# Put any additional environment here
-"""
-
-_CONFIG_FILE_NAME = 'ipython_config.py'
-
-def is_installed(ipydir=None, profile='tango'):
- ipython_dir = ipydir or get_ipython_dir()
- try:
- p_dir = ProfileDir.find_profile_dir_by_name(ipython_dir, profile)
- except ProfileDirError:
- return False
- abs_config_file_name = os.path.join(p_dir.location, _CONFIG_FILE_NAME)
- return os.path.isfile(abs_config_file_name)
-
-
-def install(ipydir=None, verbose=True, profile='tango'):
- if verbose:
- def out(msg):
- sys.stdout.write(msg)
- sys.stdout.flush()
- else:
- out = lambda x : None
-
- ipython_dir = ipydir or get_ipython_dir()
- try:
- p_dir = ProfileDir.find_profile_dir_by_name(ipython_dir, profile)
- except ProfileDirError:
- p_dir = ProfileDir.create_profile_dir_by_name(ipython_dir, profile)
- abs_config_file_name = os.path.join(p_dir.location, _CONFIG_FILE_NAME)
- create_config = True
- if os.path.isfile(abs_config_file_name):
- create_config = ask_yes_no("Tango configuration file already exists. "\
- "Do you wish to replace it?", default='y')
-
- if not create_config:
- return
-
- out("Installing tango extension to ipython... ")
-
- profile = __PROFILE.format(pytangover=PyTango.Release.version,
- ipyver=IPython.release.version)
- with open(abs_config_file_name, "w") as f:
- f.write(profile)
- f.close()
- out("[DONE]\n\n")
- out("""\
-To start ipython with tango interface simply type on the command line:
-%% ipython --profile=tango
-
-For more information goto:
-http://www.tango-controls.org/static/PyTango/latest/doc/html/
-
-Have fun with ITango!
-The PyTango team
-""")
-
-def main():
- d = None
- if len(sys.argv) > 1:
- d = sys.argv[1]
- install(d)
-
-if __name__ == "__main__":
- main()
diff --git a/src/boost/python/ipython/ipython_10_00/ipython_10_00.py b/src/boost/python/ipython/ipython_10_00/ipython_10_00.py
deleted file mode 100644
index 0ced093..0000000
--- a/src/boost/python/ipython/ipython_10_00/ipython_10_00.py
+++ /dev/null
@@ -1,1340 +0,0 @@
-# -----------------------------------------------------------------------------
-# This file is part of PyTango (http://www.tinyurl.com/PyTango)
-#
-# Copyright 2006-2012 CELLS / ALBA Synchrotron, Bellaterra, Spain
-# Copyright 2013-2014 European Synchrotron Radiation Facility, Grenoble, France
-#
-# Distributed under the terms of the GNU Lesser General Public License,
-# either version 3 of the License, or (at your option) any later version.
-# See LICENSE.txt for more info.
-# -----------------------------------------------------------------------------
-
-"""An IPython profile designed to provide a user friendly interface to Tango"""
-
-from __future__ import print_function
-
-__all__ = ["load_config", "load_ipython_extension", "unload_ipython_extension",
- "run"]
-
-import os
-import re
-import io
-import sys
-import operator
-import textwrap
-
-from IPython.core.error import UsageError
-from IPython.utils.ipstruct import Struct
-from IPython.core.page import page
-from IPython.core.interactiveshell import InteractiveShell
-try: # IPython 4.x
- from traitlets.config.application import Application
-except: # IPython < 4.x
- from IPython.config.application import Application
-from IPython.terminal.ipapp import launch_new_instance
-
-import PyTango
-import PyTango.utils
-
-
-_TG_EXCEPTIONS = PyTango.DevFailed, PyTango.ConnectionFailed, \
- PyTango.CommunicationFailed, \
- PyTango.NamedDevFailed, PyTango.NamedDevFailedList, \
- PyTango.WrongNameSyntax, PyTango.NonDbDevice, PyTango.WrongData, \
- PyTango.NonSupportedFeature, PyTango.AsynCall, \
- PyTango.AsynReplyNotArrived, PyTango.EventSystemFailed, \
- PyTango.DeviceUnlocked, PyTango.NotAllowed
-
-_DB_SYMB = "db"
-_DFT_TANGO_HOST = None
-_TANGO_STORE = "__tango_store"
-_TANGO_ERR = "__tango_error"
-_PYTHON_ERR = "__python_error"
-_tango_init = False
-
-#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
-# IPython utilities
-#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
-
-def get_pylab_mode():
- return get_app().pylab
-
-def get_color_mode():
- return get_config().InteractiveShell.colors
-
-def get_app():
- #return TerminalIPythonApp.instance()
- return Application.instance()
-
-def get_shell():
- """Get the global InteractiveShell instance."""
- return get_app().shell
-
-def get_ipapi():
- """Get the global InteractiveShell instance."""
- return InteractiveShell.instance()
-
-def get_config():
- return get_app().config
-
-def get_editor():
- return get_ipapi().editor
-
-def get_user_ns():
- return get_shell().user_ns
-
-class DeviceClassCompleter(object):
- """Completer class that returns the list of devices of some class when
- called. """
-
- def __init__(self, klass, devices):
- self._klass = klass
- self._devices = devices
-
- def __call__(self, ip, evt):
- return self._devices
-
-
-# Rewrite DeviceProxy constructor because the database context that the user is
-# using may be different than the default TANGO_HOST. What we do is always append
-# the name of the database in usage to the device name given by the user (in case
-# he doesn't give a database name him(her)self, of course.
-#__DeviceProxy_init_orig__ = PyTango.DeviceProxy.__init__
-#def __DeviceProxy__init__(self, dev_name):
-# db = __get_db()
-# if db is None: return
-# if dev_name.count(":") == 0:
-# db_name = "%s:%s" % (db.get_db_host(), db.get_db_port())
-# dev_name = "%s/%s" % (db_name, dev_name)
-# __DeviceProxy_init_orig__(self, dev_name)
-#PyTango.DeviceProxy.__init__ = __DeviceProxy__init__
-
-#-------------------------------------------------------------------------------
-# Completers
-#-------------------------------------------------------------------------------
-
-def __DeviceProxy_completer(ip, evt):
- db = __get_db()
- if db is None: return
- ret = list(db._db_cache.devices.keys())
- ret.extend(db._db_cache.aliases.keys())
- return ret
-
-def __DeviceClass_completer(ip, evt):
- db = __get_db()
- if db is None: return
- return list(db._db_cache.klasses.keys())
-
-def __DeviceAlias_completer(ip, evt):
- db = __get_db()
- if db is None: return
- return list(db._db_cache.aliases.keys())
-
-def __AttributeAlias_completer(ip, evt):
- db = __get_db()
- if db is None: return
- return list(db._db_cache.attr_aliases.keys())
-
-def __PureDeviceProxy_completer(ip, evt):
- db = __get_db()
- if db is None: return
- return list(db._db_cache.devices.keys())
-
-def __AttributeProxy_completer(ip, evt):
- db = __get_db()
- if db is None: return
- cache = db._db_cache
-
- symb = evt.symbol
- n = symb.count("/")
- ret, devs, dev_aliases = None, cache.devices, cache.aliases
- # dev_list and dev_alias_list are case insensitive. They should only be used
- # to search for elements. Their elements are the same as the keys of the
- # dictionaries devs and dev_aliases respectively
- dev_list, dev_alias_list = cache.device_list, cache.alias_list
- dev_name = None
- if n == 0:
- # means it can be an attr alias, a device name has alias or as full device name
- ret = list(cache.get("attr_aliases").keys())
- ret.extend([ d+"/" for d in devs ])
- ret.extend([ d+"/" for d in dev_aliases ])
- # device alias found!
- if symb in dev_alias_list:
- dev_name = symb
- elif n == 1:
- # it can still be a full device name
- ret = [ d+"/" for d in devs ]
- # it can also be devalias/attr_name
- dev, attr = symb.split("/")
- if dev in dev_alias_list:
- dev_name = dev
- elif n == 2:
- # it is for sure NOT an attribute alias or a device alias
- ret = [ d+"/" for d in devs ]
- # device found!
- if symb in dev_list:
- dev_name = symb
- elif n == 3:
- # it is for sure a full attribute name
- dev, sep, attr = symb.rpartition("/")
- if dev in dev_list:
- dev_name = dev
-
- if dev_name is None:
- return ret
-
- try:
- d = __get_device_proxy(dev_name)
- # first check in cache for the attribute list
- if not hasattr(d, "_attr_list"):
- d._attr_list = d.get_attribute_list()
- if ret is None:
- ret = []
- ret.extend([ "%s/%s" % (dev_name, a) for a in d._attr_list ])
- except:
- # either DeviceProxy could not be created or device is not online
- pass
-
- return ret
-
-def __get_device_proxy(dev_name):
- db = __get_db()
- if db is None: return
- cache = db._db_cache
- from_alias = cache.aliases.get(dev_name)
-
- if from_alias is not None:
- dev_name = from_alias
-
- data = cache.devices.get(dev_name)
- if data is not None:
- d = data[3]
- if d is None:
- try:
- d = data[3] = PyTango.DeviceProxy(dev_name)
- except:
- pass
- return d
-
-def __get_device_subscriptions(dev_name):
- db = __get_db()
- if db is None: return
- cache = db._db_cache
- from_alias = cache.aliases.get(dev_name)
-
- if from_alias is not None:
- dev_name = from_alias
-
- data = cache.devices.get(dev_name)
- if data is not None:
- return data[4]
-
-__monitor_completer = __AttributeProxy_completer
-
-#-------------------------------------------------------------------------------
-# Magic commands
-#-------------------------------------------------------------------------------
-
-def refreshdb(self, parameter_s=''):
- init_db(parameter_s)
-
-def switchdb(self, parameter_s=''):
- """Switches the active tango Database.
-
- Usage: switchdb <host>[(:| )<port>]
-
- <port> is optional. If not given it defaults to 10000.
-
- Examples:
- In [1]: switchdb homer:10005
- In [2]: switchdb homer 10005
- In [3]: switchdb homer"""
-
- if parameter_s == '':
- raise UsageError("%switchdb: Must specify a tango database name. "\
- "See '%switchdb?'")
- return init_db(parameter_s)
-
-def lsdev(self, parameter_s=''):
- """Lists all known tango devices.
-
- Usage: lsdev [<device name filter(regular expression)]
-
- Examples:
- In [1]: lsdev
- In [2]: lsdev sys.*"""
-
- if parameter_s:
- reg_exp = re.compile(parameter_s, re.IGNORECASE)
- else:
- reg_exp = None
-
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database. Device list is empty")
- return
- data = db._db_cache.devices
-
- s = io.StringIO()
- lengths = 40, 25, 25, 20
- title = "Device", "Alias", "Server", "Class"
- templ = "{0:{l[0]}} {1:{l[1]}} {2:{l[2]}} {3:{l[3]}}"
- msg = templ.format(*title, l=lengths)
- print(msg, file=s)
- print(*map(operator.mul, lengths, len(lengths)*"-"), file=s)
- for d, v in data.items():
- if reg_exp and not reg_exp.match(d):
- continue
- print(templ.format(d, v[0], v[1], v[2], l=lengths), file=s)
- s.seek(0)
- page(s.read())
-
-def lsdevclass(self, parameter_s=''):
- """Lists all known tango device classes.
-
- Usage: lsdevclass [<class name filter(regular expression)]
-
- Examples:
- In [1]: lsdevclass
- In [2]: lsdevclass Motor.*"""
-
- if parameter_s:
- reg_exp = re.compile(parameter_s, re.IGNORECASE)
- else:
- reg_exp = None
-
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database. Device class list is empty")
- return
- data = db._db_cache.klasses
-
- data = [ "%-030s" % klass for klass in data.keys() if not reg_exp or reg_exp.match(klass) ]
- s = textwrap.fill(" ".join(data), 80)
- page(s)
-
-def lsserv(self, parameter_s=''):
- """Lists all known tango servers.
-
- Usage: lsserv [<class name filter(regular expression)]
-
- Examples:
- In [1]: lsserv
- In [2]: lsserv Motor/.*"""
-
- if parameter_s:
- reg_exp = re.compile(parameter_s, re.IGNORECASE)
- else:
- reg_exp = None
-
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database. Device class list is empty")
- return
- data = db._db_cache.servers
-
- data = [ "%-030s" % server for server in data.keys() if not reg_exp or reg_exp.match(server) ]
- s = textwrap.fill(" ".join(data), 80)
- page(s)
-
-def tango_error(self, parameter_s=''):
- """Displays detailed information about the last tango error"""
- global _TANGO_ERR
- err_info = get_user_ns().get(_TANGO_ERR)
- if err_info is None:
- print("No tango error reported so far.")
- return
- print("Last tango error:")
- print(err_info[1])
-
-def python_error(self, parameter_s=''):
- """Displays detailed information about the last python error"""
- global _PYTHON_ERR
- err_info = get_user_ns().get(_PYTHON_ERR)
- if err_info is None:
- print("No error reported so far.")
- return
- ip = get_ipapi()
- etype, evalue, etb = err_info[:3]
- ip.InteractiveTB(etype=etype, evalue=evalue, etb=etb, tb_offset=None)
-
-_EVT_LOG = None
-def __get_event_log():
- global _EVT_LOG
- if _EVT_LOG is None:
-# qthreads = get_config().q4thread
-# if qthreads:
-# import ipy_qt
-# model = ipy_qt.EventLoggerTableModel(capacity=10000)
-# _EVT_LOG = ipy_qt.EventLogger(model=model)
-# _EVT_LOG.setWindowTitle("ITango - Event Logger Table")
-# else:
- import PyTango.ipython.eventlogger
- _EVT_LOG = PyTango.ipython.eventlogger.EventLogger(capacity=10000, pager=page)
- return _EVT_LOG
-
-def mon(self, parameter_s=''):
- """Monitor a given attribute.
-
- %mon -a <attribute name> - activates monitoring of given attribute
- %mon -d <attribute name> - deactivates monitoring of given attribute
- %mon -r - deactivates monitoring of all attributes
- %mon -i <id> - displays detailed information for the event with given id
- %mon -l <dev filter> <attr filter> - shows event table filtered with the regular expression for attribute name
- %mon - shows event table (= %mon -i .* .*)"""
-
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
-
- # make sure parameter_s is a str and not a unicode
- parameter_s = str(parameter_s)
- opts, args = self.parse_options(parameter_s,'adril', mode='list')
- if len(args) > 3:
- raise UsageError("%mon: too many arguments")
- if 'd' in opts:
- try:
- todel = args[0]
- except IndexError:
- raise UsageError("%mon -d: must provide an attribute to unmonitor")
- else:
- try:
- dev, _, attr = todel.rpartition("/")
- subscriptions = __get_device_subscriptions(dev)
- attr_id = subscriptions[attr.lower()]
- del subscriptions[attr.lower()]
- d = __get_device_proxy(dev)
- d.unsubscribe_event(attr_id)
- print("Stopped monitoring '%s'" % todel)
- except KeyError:
- raise UsageError("%%mon -d: Not monitoring '%s'" % todel)
-
- elif 'a' in opts:
- try:
- toadd = args[0]
- except IndexError:
- raise UsageError("%mon -a: must provide an attribute to monitor")
- dev, _, attr = toadd.rpartition("/")
- subscriptions = __get_device_subscriptions(dev)
- attr_id = subscriptions.get(attr.lower())
- if attr_id is not None:
- raise UsageError("%%mon -a: Already monitoring '%s'" % toadd)
- d = __get_device_proxy(dev)
- w = __get_event_log()
- model = w.model()
- attr_id = d.subscribe_event(attr, PyTango.EventType.CHANGE_EVENT,
- model, [])
- subscriptions[attr.lower()] = attr_id
- print("'%s' is now being monitored. Type 'mon' to see all events" % toadd)
- elif 'r' in opts:
- for d, v in db._db_cache.devices.items():
- d, subs = v[3], v[4]
- for _id in subs.values():
- d.unsubscribe_event(_id)
- v[4] = {}
- elif 'i' in opts:
- try:
- evtid = int(args[0])
- except IndexError:
- raise UsageError("%mon -i: must provide an event ID")
- except ValueError:
- raise UsageError("%mon -i: must provide a valid event ID")
- try:
- w = __get_event_log()
- e = w.getEvents()[evtid]
- if e.err:
- print(str(PyTango.DevFailed(*e.errors)))
- else:
- print(str(e))
- except IndexError:
- raise UsageError("%mon -i: must provide a valid event ID")
- elif 'l' in opts:
- try:
- dexpr = args[0]
- aexpr = args[1]
- except IndexError:
- raise UsageError("%mon -l: must provide valid device and " \
- "attribute filters")
- w = __get_event_log()
- w.show(dexpr, aexpr)
- else:
- w = __get_event_log()
- w.show()
-
-#-------------------------------------------------------------------------------
-# Useful functions (not magic commands but accessible from CLI as normal python
-# functions)
-#-------------------------------------------------------------------------------
-
-def get_device_map():
- """Returns a dictionary where keys are device names and value is a sequence
- of 4 elements:
- - alias name (empty string if no alias is defined)
- - tango server name (full tango server name <name>/<instance>)
- - tango class name
- - DeviceProxy to the device or None if it hasn't been initialized yet
- (this last element is for internal tango usage only. If you need a
- DeviceProxy to this device, create your own)"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.devices
-
-def get_server_map():
- """Returns a dictionary where keys are server names (<name>/<instance>)
- and value is a sequence of device names that belong to the server"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.servers
-
-def get_class_map():
- """Returns a dictionary where keys are the tango classes and value is a
- sequence of device names that belong to the tango class"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.klasses
-
-def get_alias_map():
- """Returns a dictionary where keys are the tango device aliases and value
- is a the tango device name"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.aliases
-
-def get_device_list():
- """Returns a case insensitive list of device names for the current
- database"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.device_list
-
-def get_alias_list():
- """Returns a case insensitive list of device aliases for the current
- database"""
- db = __get_db()
- if db is None:
- print("You are not connected to any Tango Database.")
- return
- return db._db_cache.alias_list
-
-#-------------------------------------------------------------------------------
-# Private helper methods
-#-------------------------------------------------------------------------------
-
-def __exc_handler(ip, etype, value, tb, tb_offset=None):
- global _TG_EXCEPTIONS
- user_ns = get_user_ns()
- if etype in _TG_EXCEPTIONS:
- global _TANGO_ERR
- user_ns[_TANGO_ERR] = etype, value, tb, tb_offset
- if len(value.args):
- v = value.args[0]
- print("%s: %s" % (v.reason ,v.desc))
- else:
- print("Empty DevFailed")
- print("(For more detailed information type: tango_error)")
- else:
- global _PYTHON_ERR
- user_ns[_PYTHON_ERR] = etype, value, tb, tb_offset
- print(etype.__name__ + ": " + str(value))
- print("(For more detailed information type: python_error)")
-
-def __get_default_tango_host():
- global _DFT_TANGO_HOST
- if _DFT_TANGO_HOST is None:
- try:
- db = PyTango.Database()
- _DFT_TANGO_HOST = "%s:%s" % (db.get_db_host(), db.get_db_port())
- except:
- pass
- return _DFT_TANGO_HOST
-
-def __get_db(host_port=None):
- """host_port == None: Use current DB whatever it is or create
- default if doesn't exist
- host_port == '' : use default db. If it is not the current db, switch
- current db to it and return it
- host_port == ... : if ... is not the current db, switch current db to it
- and return it
- """
-
- ip = get_ipapi()
- user_ns = get_user_ns()
-
- global _DB_SYMB
- db = user_ns.get(_DB_SYMB)
-
- if host_port is None:
- if db is None:
- host_port = __get_default_tango_host()
- elif host_port == '':
- host_port = __get_default_tango_host()
- else:
- host_port = host_port.strip().replace(" ",":")
- if host_port.count(":") == 0:
- host_port += ":10000"
-
- if host_port is not None:
- host_port = str(host_port)
-
- if db is None:
- create_db = True
- elif host_port is None:
- create_db = False
- else:
- old_host_port = "%s:%s" % (db.get_db_host(), db.get_db_port())
- create_db = old_host_port != host_port
-
- if create_db:
- try:
- db = PyTango.Database(*host_port.split(":"))
-
- user_ns["DB_NAME"] = host_port
- except Exception as e:
- if db:
- print("\nCould not access Database %s:" % host_port)
- print(str(e))
- old_host_port = "%s:%s" % (db.get_db_host(), db.get_db_port())
- print("Maintaining connection to Database", old_host_port)
- user_ns["DB_NAME"] = old_host_port
- else:
- print("\nCould not access any Database. Make sure:")
- print("\t- .tangorc, /etc/tangorc or TANGO_HOST environment is defined.")
- print("\t- the Database DS is running")
- user_ns["DB_NAME"] = "OFFLINE"
-
- # register the 'db' in the user namespace
- user_ns.update({ _DB_SYMB : db })
-
- return db
-
-def __get_obj_name(o):
- try:
- n = o.__name__
- except:
- try:
- n = o.__class__.__name__
- except:
- n = "<unknown>"
- return n
-
-def __completer_wrapper(f):
- def wrapper(ip, evt):
- try:
- return f(ip, evt)
- except Exception as e:
- print()
- print("An unexpected exception ocorred during ITango command completer.")
- print("Please send a bug report to the PyTango team with the following information:")
- print(80*"-")
- print("Completer:",__get_obj_name(f))
- print(80*"-")
- import traceback
- traceback.print_exc()
- print(80*"-")
- raise e
- return wrapper
-
-def __expose_magic(ip, name, fn, completer_func=None):
- ip.define_magic(name, fn)
-
- if completer_func is None:
- return
-
- # enable macro param completion
- ip.set_hook('complete_command', completer_func, re_key = ".*" + name)
-
-def __unexpose_magic(ip, name):
- delattr(ip, name)
-
-def __build_color_scheme(ip, name):
- import IPython.Prompts
- import IPython.PyColorize
- import IPython.excolors
- from IPython.utils.coloransi import TermColors, InputTermColors
-
- # make some schemes as instances so we can copy them for modification easily:
- PromptColors = IPython.Prompts.PromptColors
- ANSICodeColors = IPython.PyColorize.ANSICodeColors
- ExceptionColors = IPython.excolors.ExceptionColors
- TBColors = ip.IP.InteractiveTB.color_scheme_table
- SyntaxColors = ip.IP.SyntaxTB.color_scheme_table
- InspectColors = IPython.OInspect.InspectColors
-
- promptTangoColors = PromptColors['Linux'].copy(name)
- ANSITangoColors = ANSICodeColors['Linux'].copy(name)
- exceptionTangoColors = ExceptionColors['Linux'].copy(name)
- TBTangoColors = TBColors['Linux'].copy(name)
- syntaxTangoColors = SyntaxColors['Linux'].copy(name)
- inspectTangoColors = InspectColors['Linux'].copy(name)
-
- # initialize prompt with default tango colors
- promptTangoColors.colors.in_prompt = InputTermColors.Purple
- promptTangoColors.colors.in_number = InputTermColors.LightPurple
- promptTangoColors.colors.in_prompt2 = InputTermColors.Purple
- promptTangoColors.colors.out_prompt = TermColors.Blue
- promptTangoColors.colors.out_number = TermColors.LightBlue
-
- ret= { "prompt" : (PromptColors, promptTangoColors),
- "ANSI" : (ANSICodeColors, ANSITangoColors),
- "except" : (ExceptionColors, exceptionTangoColors),
- "TB" : (TBColors, TBTangoColors),
- "Syntax" : (SyntaxColors, syntaxTangoColors),
- "Inspect": (InspectColors, inspectTangoColors) }
-
- if ip.IP.isthreaded:
- TBThreadedColors = ip.IP.sys_excepthook.color_scheme_table
- TBThreadedTangoColors = TBThreadedColors['Linux'].copy(name)
- ret["TBThreaded"] = TBThreadedColors, TBThreadedTangoColors
- return ret
-
-#-------------------------------------------------------------------------------
-# Initialization methods
-#-------------------------------------------------------------------------------
-
-def init_pytango(ip):
- """Initializes the IPython environment with PyTango elements"""
-
- # export symbols to IPython namepspace
- ip.ex("import PyTango")
- ip.ex("from PyTango import DeviceProxy, AttributeProxy, Database, Group")
- ip.ex("Device = DeviceProxy")
- ip.ex("Attribute = AttributeProxy")
-
- # add completers
- dp_completer = __completer_wrapper(__DeviceProxy_completer)
- attr_completer = __completer_wrapper(__AttributeProxy_completer)
- ip.set_hook('complete_command', dp_completer, re_key = ".*DeviceProxy[^\w\.]+")
- ip.set_hook('complete_command', dp_completer, re_key = ".*Device[^\w\.]+")
- ip.set_hook('complete_command', attr_completer, re_key = ".*AttributeProxy[^\w\.]+")
- ip.set_hook('complete_command', attr_completer, re_key = ".*Attribute[^\w\.]+")
-
- ip.set_custom_exc((Exception,), __exc_handler)
-
-def init_db(parameter_s=''):
- ip = get_ipapi()
- user_ns = get_user_ns()
- global _DB_SYMB
- old_db = user_ns.get(_DB_SYMB)
-
- db = __get_db(parameter_s)
-
- if old_db is not None and hasattr(old_db, "_db_cache"):
- old_junk = old_db._db_cache["junk"].keys()
- for e in old_junk:
- del user_ns[e]
- else:
- old_junk = ()
-
- if db is None: return
-
- os.environ["TANGO_HOST"] = "%s:%s" % (db.get_db_host(), db.get_db_port())
-
- # Initialize device and server information
- query = "SELECT name, alias, server, class FROM device order by name"
-
- r = db.command_inout("DbMySqlSelect", query)
- row_nb, column_nb = r[0][-2], r[0][-1]
- data = r[1]
- assert row_nb == len(data) / column_nb
- devices, aliases, servers, klasses = data[0::4], data[1::4], data[2::4], data[3::4]
-
- #CD = PyTango.utils.CaselessDict
- CD = dict
- dev_dict, serv_dict, klass_dict, alias_dict = CD(), CD(), CD(), CD()
-
- for device, alias, server, klass in zip(devices, aliases, servers, klasses):
- dev_lower = device.lower()
-
- # hide dserver devices
- if dev_lower.startswith("dserver/"): continue
-
- # hide alias that start with "_"
- if alias and alias[0] == "_": alias = ''
-
- # last None below is to be filled by DeviceProxy object on demand
- # last empty dict<str, int> where keys is attribute name and value is
- # the subscription id
- dev_dict[device] = [alias, server, klass, None, {}]
- serv_devs = serv_dict.get(server)
- if serv_devs is None:
- serv_dict[server] = serv_devs = []
- serv_devs.append(device)
- klass_devs = klass_dict.get(klass)
- if klass_devs is None:
- klass_dict[klass] = klass_devs = []
- klass_devs.append(device)
- if len(alias):
- alias_dict[alias] = device
- serv_devs.append(alias)
- klass_devs.append(alias)
-
- exposed_klasses = {}
- excluded_klasses = "DServer",
- for klass, devices in klass_dict.items():
- if klass in excluded_klasses:
- continue
- exists = klass in user_ns
- if not exists or klass in old_junk:
- c = DeviceClassCompleter(klass, devices)
- ip.set_hook('complete_command', c, re_key = ".*" + klass + "[^\w\.]+")
- exposed_klasses[klass] = PyTango.DeviceProxy
-
- # expose classes no user namespace
- user_ns.update(exposed_klasses)
-
- # Initialize attribute information
- query = "SELECT name, alias FROM attribute_alias order by alias"
-
- r = db.command_inout("DbMySqlSelect", query)
- row_nb, column_nb = r[0][-2], r[0][-1]
- data = r[1]
- assert row_nb == len(data) / column_nb
- attributes, aliases = data[0::2], data[1::2]
-
- attr_alias_dict = {}
- for attribute, alias in zip(attributes, aliases):
- if len(alias):
- attr_alias_dict[alias] = attribute
-
- device_list = PyTango.utils.CaselessList(dev_dict.keys())
- alias_list = PyTango.utils.CaselessList(alias_dict.keys())
- attr_alias_list = PyTango.utils.CaselessList(attr_alias_dict.keys())
-
- # Build cache
- db_cache = Struct(devices=dev_dict, aliases=alias_dict,
- servers=serv_dict, klasses=klass_dict, junk=exposed_klasses,
- attr_aliases=attr_alias_dict, device_list=device_list,
- alias_list=alias_list, attr_alias_list=attr_alias_list)
-
- db._db_cache = db_cache
-
- # Add this DB to the list of known DBs (for possible use in magic commands)
- if db.get_db_port_num() == 10000:
- db_name = db.get_db_host()
- else:
- db_name = "%s:%s" % (db.get_db_host(), db.get_db_port())
- return db
-
-def init_magic(ip):
-
- import IPython.core.magic
-
- new_style_magics = hasattr(IPython.core.magic, 'Magics') and hasattr(IPython.core.magic, 'magics_class')
-
- if new_style_magics:
- @IPython.core.magic.magics_class
- class Tango(IPython.core.magic.Magics):
-
- refreshdb = IPython.core.magic.line_magic(refreshdb)
- switchdb = IPython.core.magic.line_magic(switchdb)
- lsdev = IPython.core.magic.line_magic(lsdev)
- lsdevclass = IPython.core.magic.line_magic(lsdevclass)
- lsserv = IPython.core.magic.line_magic(lsserv)
- tango_error = IPython.core.magic.line_magic(tango_error)
- python_error = IPython.core.magic.line_magic(python_error)
- mon = IPython.core.magic.line_magic(mon)
-
- ip.register_magics(Tango)
- ip.set_hook('complete_command', __monitor_completer, re_key = ".*" + "mon")
- else:
- __expose_magic(ip, "refreshdb", refreshdb)
- __expose_magic(ip, "switchdb", switchdb)
- __expose_magic(ip, "lsdev", lsdev)
- __expose_magic(ip, "lsdevclass", lsdevclass)
- __expose_magic(ip, "lsserv", lsserv)
- __expose_magic(ip, "tango_error", tango_error)
- __expose_magic(ip, "python_error", python_error)
- __expose_magic(ip, "mon", mon, __monitor_completer)
-
- get_user_ns().update({"get_device_map" : get_device_map,
- "get_server_map" : get_server_map,
- "get_class_map" : get_class_map,
- "get_alias_map" : get_alias_map,
- "get_device_list" : get_device_list,
- "get_alias_list" : get_alias_list})
-
-def complete(text):
- """a super complete!!!!"""
- self = get_ipapi().IP
- complete = self.Completer.complete
- state = 0
- comps = set()
- while True:
- newcomp = complete("", state, line_buffer=text)
- if newcomp is None:
- break
- comps.add(newcomp)
- state += 1
- outcomps = sorted(comps)
- return outcomps
-
-__DIRNAME = os.path.dirname(os.path.abspath(__file__))
-__RES_DIR = os.path.join(__DIRNAME, os.path.pardir, 'resource')
-
-class __TangoDeviceInfo(object):
- """Helper class for when DeviceProxy.info() is not available"""
-
- def __init__(self, dev):
- try:
- db = dev.get_device_db()
- klass = db.get_class_for_device(dev.dev_name())
- self.dev_class = self.dev_type = klass
- except:
- self.dev_class = self.dev_type = 'Device'
- self.doc_url = 'http://www.esrf.eu/computing/cs/tango/tango_doc/ds_doc/index.html'
- self.server_host = 'Unknown'
- self.server_id = 'Unknown'
- self.server_version = 1
-
-
-def __get_device_class_icon(klass="Device"):
- icon_prop = "__icon"
- db = __get_db()
- try:
- icon_filename = db.get_class_property(klass, icon_prop)[icon_prop]
- if icon_filename:
- icon_filename = icon_filename[0]
- else:
- icon_filename = klass.lower() + os.path.extsep + "png"
- except:
- icon_filename = klass.lower() + os.path.extsep + "png"
-
- if os.path.isabs(icon_filename):
- icon = icon_filename
- else:
- icon = os.path.join(__RES_DIR, icon_filename)
- if not os.path.isfile(icon):
- icon = os.path.join(__RES_DIR, "_class.png")
- return icon
-
-
-__DEV_CLASS_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td width="140" rowspan="7" valign="middle" align="center"><img src="{icon}" height="128"/></td>
- <td width="140">Name:</td><td><b>{name}</b></td></tr>
-<tr><td width="140">Super class:</td><td>{super_class}</td></tr>
-<tr><td width="140">Database:</td><td>{database}</td></tr>
-<tr><td width="140">Description:</td><td>{description}</td></tr>
-<tr><td width="140">Documentation:</td><td><a target="_blank" href="{doc_url}">{doc_url}</a></td></tr>
-</table>"""
-
-def __get_class_property_str(dev_class, prop_name, default=""):
- data = __get_db().get_class_property(dev_class, prop_name)[prop_name]
- if len(data):
- return data[0]
- else:
- return default
-
-def display_deviceclass_html(dev_class):
- """displayhook function for PyTango.DeviceProxy, rendered as HTML"""
- fmt = dict(name=dev_class)
- db = __get_db()
- try:
- fmt["database"] = db.get_db_host() + ":" + db.get_db_port()
- except:
- try:
- fmt["database"] = db.get_file_name()
- except:
- fmt["database"] = "Unknown"
-
- doc_url = __get_class_property_str(dev_class, "doc_url", "www.tango-controls.org")
- try:
- fmt["doc_url"] = doc_url[doc_url.index("http"):]
- except ValueError:
- fmt["doc_url"] = doc_url
-
- fmt['icon'] = __get_device_class_icon(dev_class)
- fmt['super_class'] = __get_class_property_str(dev_class, "InheritedFrom", "DeviceImpl")
- fmt['description'] = __get_class_property_str(dev_class, "Description", "A Tango device class")
- return __DEV_CLASS_HTML_TEMPLATE.format(**fmt)
-
-
-def __get_device_icon(dev_proxy, klass="Device"):
- icon_prop = "__icon"
- db = dev_proxy.get_device_db()
- try:
- icon_filename = dev_proxy.get_property(icon_prop)[icon_prop]
- if icon_filename:
- icon_filename = icon_filename[0]
- else:
- icon_filename = db.get_class_property(klass, icon_prop)[icon_prop]
- if icon_filename:
- icon_filename = icon_filename[0]
- else:
- icon_filename = klass.lower() + os.path.extsep + "png"
- except:
- icon_filename = klass.lower() + os.path.extsep + "png"
-
- if os.path.isabs(icon_filename):
- icon = icon_filename
- else:
- icon = os.path.join(__RES_DIR, icon_filename)
- if not os.path.isfile(icon):
- icon = os.path.join(__RES_DIR, "device.png")
- return icon
-
-__DEV_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td width="140" rowspan="7" valign="middle" align="center"><img src="{icon}" height="128"/></td>
- <td width="140">Name:</td><td><b>{name}</b></td></tr>
-<tr><td width="140">Alias:</td><td>{alias}</td></tr>
-<tr><td width="140">Database:</td><td>{database}</td></tr>
-<tr><td width="140">Type:</td><td>{dev_class}</td></tr>
-<tr><td width="140">Server:</td><td>{server_id}</td></tr>
-<tr><td width="140">Server host:</td><td>{server_host}</td></tr>
-<tr><td width="140">Documentation:</td><td><a target="_blank" href="{doc_url}">{doc_url}</a></td></tr>
-</table>"""
-
-def display_deviceproxy_html(dev_proxy):
- """displayhook function for PyTango.DeviceProxy, rendered as HTML"""
- try:
- info = dev_proxy.info()
- except:
- info = __TangoDeviceInfo(dev_proxy)
- name = dev_proxy.dev_name()
- fmt = dict(dev_class=info.dev_class, server_id=info.server_id,
- server_host=info.server_host, name=name)
-
- try:
- fmt["alias"] = dev_proxy.alias()
- except:
- fmt["alias"] = "-----"
-
- db = dev_proxy.get_device_db()
- try:
- fmt["database"] = db.get_db_host() + ":" + db.get_db_port()
- except:
- try:
- fmt["database"] = db.get_file_name()
- except:
- fmt["database"] = "Unknown"
-
- doc_url = info.doc_url.split("\n")[0]
- try:
- fmt["doc_url"] = doc_url[doc_url.index("http"):]
- except ValueError:
- fmt["doc_url"] = doc_url
-
- fmt['icon'] = __get_device_icon(dev_proxy, info.dev_class)
-
- return __DEV_HTML_TEMPLATE.format(**fmt)
-
-__DB_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td width="140" rowspan="2" valign="middle" align="center"><img src="{icon}" height="128"/></td>
- <td><b>{name}</b></td></tr>
-<tr><td>{info}</td></tr>
-</table>"""
-
-def display_database_html(db):
- """displayhook function for PyTango.Database, rendered as HTML"""
- fmt = dict()
-
- try:
- fmt["name"] = db.get_db_host() + ":" + db.get_db_port()
- except:
- try:
- fmt["name"] = db.get_file_name()
- except:
- fmt["name"] = "Unknown"
-
- try:
- fmt["info"] = db.get_info().replace("\n", "<BR/>")
- except:
- fmt["info"] = "Unknown"
-
- fmt['icon'] = os.path.join(__RES_DIR, "database.png")
-
- return __DB_HTML_TEMPLATE.format(**fmt)
-
-__DEV_ATTR_RW_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td colspan="2" bgcolor="{bgcolor}">{name} ({type}, {data_format}, {quality}) at {time}</td></tr>
-<tr><td bgcolor="#EEEEEE" width="140">value{r_dim}:</td>
- <td bgcolor="#EEEEEE">{value}</td></tr>
-<tr><td bgcolor="#EEEEEE" width="140">w_value{w_dim}:</td>
- <td bgcolor="#EEEEEE">{w_value}</td></tr>
-</table>"""
-
-__DEV_ATTR_RO_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td colspan="2" bgcolor="{bgcolor}">{name} ({type}, {data_format}, {quality}) at {time}</td></tr>
-<tr><td bgcolor="#EEEEEE" width="140">value{r_dim}:</td>
- <td bgcolor="#EEEEEE">{value}</td></tr>
-</table>"""
-
-__DEV_ATTR_ERR_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td bgcolor="#FF0000">{name} ({type}, {data_format}, {quality}) at {time}</td></tr>
-<tr><td bgcolor="#EEEEEE">{error}</td></tr>
-</table>"""
-
-QUALITY_TO_HEXCOLOR_STR = {
- PyTango.AttrQuality.ATTR_VALID : ("#00FF00", "#000000"),
- PyTango.AttrQuality.ATTR_INVALID : ("#808080", "#FFFFFF"),
- PyTango.AttrQuality.ATTR_ALARM : ("#FF8C00", "#FFFFFF"),
- PyTango.AttrQuality.ATTR_WARNING : ("#FF8C00", "#FFFFFF"),
- PyTango.AttrQuality.ATTR_CHANGING : ("#80A0FF", "#000000"),
- None : ("#808080", "#000000"),
-}
-
-def display_deviceattribute_html(da):
- """displayhook function for PyTango.DeviceAttribute, rendered as HTML"""
- fmt = dict(name=da.name, type=da.type, data_format=da.data_format)
- template = None
- if da.has_failed:
- fmt['error'] = "\n".join(map(str, da.get_err_stack())).replace("\n", "<br/>")
-
- template = __DEV_ATTR_ERR_HTML_TEMPLATE
- else:
- rd, wd = da.r_dimension, da.w_dimension
- if wd.dim_x == 0 and wd.dim_y == 0 and da.w_value is None:
- template = __DEV_ATTR_RO_HTML_TEMPLATE
- else:
- template = __DEV_ATTR_RW_HTML_TEMPLATE
- fmt['w_value'] = str(da.w_value)
- if da.data_format == PyTango.AttrDataFormat.SCALAR:
- fmt['w_dim'] = ""
- else:
- fmt['w_dim'] = "<br/>(%d, %d)" % (wd.dim_x, wd.dim_y)
- fmt['bgcolor'], fmt['fgcolor'] = QUALITY_TO_HEXCOLOR_STR[da.quality]
- fmt['quality'] = str(da.quality)
- if da.data_format == PyTango.AttrDataFormat.SCALAR:
- fmt['r_dim'] = ""
- else:
- fmt['r_dim'] = "<br/>(%d, %d)" % (rd.dim_x, rd.dim_y)
- fmt['value'] = str(da.value)
- fmt['time'] = str(da.time.todatetime())
- return template.format(**fmt)
-
-__GROUP_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td width="100" bgcolor="#EEEEEE">Name:</td><td bgcolor="#EEEEEE">{name}</td></tr>
-<tr><td width="100" bgcolor="#EEEEEE">Size:</td><td bgcolor="#EEEEEE">{size}</td></tr>
-<tr><td width="100" bgcolor="#EEEEEE">Devices:</td><td bgcolor="#EEEEEE">{devices}</td></tr>
-</table>"""
-
-def display_group_html(group):
- devices = group.get_device_list()
- devices = ", ".join(devices)
- fmt=dict(name=group.get_name(), size=group.get_size(), devices=devices)
- return __GROUP_HTML_TEMPLATE.format(**fmt)
-
-__GROUP_REPLY_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td bgcolor="#EEEEEE">{name}</td></tr>
-<tr><td>{data}</td></tr>
-"""
-
-__GROUP_REPLY_ERR_HTML_TEMPLATE = """\
-<table border="0" cellpadding="2" width="100%">
-<tr><td bgcolor="#FF0000">{name}</td></tr>
-<tr><td bgcolor="#EEEEEE">{error}</td></tr>
-</table>"""
-
-def display_groupreply_html(gr):
- fmt = dict(name="%s/%s" % (gr.dev_name(), gr.obj_name()))
- template = None
- if gr.has_failed():
- fmt['error'] = "\n".join(map(str, gr.get_err_stack())).replace("\n", "<br/>")
- template = __GROUP_REPLY_ERR_HTML_TEMPLATE
- else:
- template = __GROUP_REPLY_HTML_TEMPLATE
- data = gr.get_data()
- if isinstance(data, PyTango.DeviceAttribute):
- data = display_deviceattribute_html(data)
- fmt["data"] = data
-
- ret = template.format(**fmt)
- return ret
-
-def init_display(ip):
- html_formatter = ip.display_formatter.formatters["text/html"]
- html_formatter.for_type(PyTango.DeviceProxy, display_deviceproxy_html)
- html_formatter.for_type(PyTango.Database, display_database_html)
- html_formatter.for_type(PyTango.DeviceAttribute, display_deviceattribute_html)
- html_formatter.for_type(PyTango.Group, display_group_html)
- html_formatter.for_type(PyTango.GroupAttrReply, display_groupreply_html)
- html_formatter.for_type(PyTango.GroupCmdReply, display_groupreply_html)
-
-
-def init_ipython(ip=None, store=True, pytango=True, colors=True, console=True,
- magic=True):
-
- if ip is None:
- ip = get_ipapi()
-
- global _tango_init
- if _tango_init is True: return
-
- init_display(ip)
-
- if pytango:
- init_pytango(ip)
-
- init_db()
-
- if magic:
- init_magic(ip)
-
- _tango_init = True
-
-def load_config(config):
- import PyTango.ipython
- import IPython.utils.coloransi
-
- d = { "version" : str(PyTango.ipython.get_pytango_version()),
- "pyver" : str(PyTango.ipython.get_python_version()),
- "ipyver" : str(PyTango.ipython.get_ipython_version()),
- "pytangover" : str(PyTango.ipython.get_pytango_version()), }
- d.update(IPython.utils.coloransi.TermColors.__dict__)
-
- so = Struct(
- tango_banner="""%(Blue)shint: Try typing: mydev = Device("%(LightBlue)s<tab>%(Normal)s\n""")
-
- so = config.get("tango_options", so)
-
- ipy_ver = PyTango.ipython.get_ipython_version()
-
- # ------------------------------------
- # Application
- # ------------------------------------
- app = config.Application
- app.log_level = 30
-
- # ------------------------------------
- # InteractiveShell
- # ------------------------------------
- i_shell = config.InteractiveShell
- i_shell.colors = 'Linux'
-
- # ------------------------------------
- # PromptManager (ipython >= 0.12)
- # ------------------------------------
- prompt = config.PromptManager
- prompt.in_template = 'ITango [\\#]: '
- prompt.out_template = 'Result [\\#]: '
-
- # ------------------------------------
- # InteractiveShellApp
- # ------------------------------------
- i_shell_app = config.InteractiveShellApp
- extensions = getattr(i_shell_app, 'extensions', [])
- extensions.append('PyTango.ipython')
- i_shell_app.extensions = extensions
-
- # ------------------------------------
- # TerminalIPythonApp: options for the IPython terminal (and not Qt Console)
- # ------------------------------------
- term_app = config.TerminalIPythonApp
- term_app.display_banner = True
- #term_app.nosep = False
- #term_app.classic = True
-
- # ------------------------------------
- # IPKernelApp: options for the Qt Console
- # ------------------------------------
- #kernel_app = config.IPKernelApp
- ipython_widget = config.IPythonWidget
- ipython_widget.in_prompt = 'ITango [<span class="in-prompt-number">%i</span>]: '
- ipython_widget.out_prompt = 'Result [<span class="out-prompt-number">%i</span>]: '
-
- #zmq_i_shell = config.ZMQInteractiveShell
-
- # ------------------------------------
- # TerminalInteractiveShell
- # ------------------------------------
- term_i_shell = config.TerminalInteractiveShell
- banner = """\
-%(Purple)sITango %(version)s%(Normal)s -- An interactive %(Purple)sTango%(Normal)s client.
-
-Running on top of Python %(pyver)s, IPython %(ipyver)s and PyTango %(pytangover)s
-
-help -> ITango's help system.
-object? -> Details about 'object'. ?object also works, ?? prints more.
-"""
-
- banner = banner % d
- banner = banner.format(**d)
- tango_banner = so.tango_banner % d
- tango_banner = tango_banner.format(**d)
- all_banner = "\n".join((banner, tango_banner))
-
- term_i_shell.banner1 = banner
- term_i_shell.banner2 = tango_banner
-
- # ------------------------------------
- # FrontendWidget
- # ------------------------------------
- frontend_widget = config.ITangoConsole
- frontend_widget.banner = all_banner
-
-def load_ipython_extension(ipython):
- # The ``ipython`` argument is the currently active
- # :class:`InteractiveShell` instance that can be used in any way.
- # This allows you do to things like register new magics, plugins or
- # aliases.
- init_ipython(ip=ipython, store=False, colors=False)
-
-def unload_ipython_extension(ipython):
- # If you want your extension to be unloadable, put that logic here.
- #print "Unloading PyTango IPython extension"
- pass
-
-
-def patch_qt_console():
- # overwrite the original IPython Qt widget with our own so we can put a
- # customized banner.
- try: # IPython 4.x
- from traitlets import Unicode
- except ImportError: # IPython < 4.x
- from IPython.utils.traitlets import Unicode
-
- try: # qtconsole
- from qtconsole.rich_ipython_widget import RichIPythonWidget
- from qtconsole.qtconsoleapp import IPythonQtConsoleApp
- except ImportError: # No qtconsole
- from IPython.qt.console.rich_ipython_widget import RichIPythonWidget
- from IPython.qt.console.qtconsoleapp import IPythonQtConsoleApp
-
- class ITangoConsole(RichIPythonWidget):
-
- banner = Unicode(config=True)
-
- def _banner_default(self):
- config = get_config()
- return config.ITangoConsole.banner
-
- IPythonQtConsoleApp.widget_factory = ITangoConsole
-
-
-def run(qt=False):
- argv = sys.argv
-
- try:
- for i, arg in enumerate(argv[:1]):
- if arg.startswith('--profile='):
- break
- else:
- argv.append("--profile=tango")
- except:
- pass
-
- if qt:
- patch_qt_console()
- if not 'qtconsole' in argv:
- argv.insert(1, 'qtconsole')
- argv.append('--pylab=inline')
-
- launch_new_instance()
diff --git a/src/boost/python/ipython/resource/ITangoConsole.svg b/src/boost/python/ipython/resource/ITangoConsole.svg
deleted file mode 100644
index b044582..0000000
--- a/src/boost/python/ipython/resource/ITangoConsole.svg
+++ /dev/null
@@ -1,422 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- inkscape:export-ydpi="90"
- inkscape:export-xdpi="90"
- inkscape:export-filename="/Users/matthiasbussonnier/Desktop/IPythonConsole.png"
- sodipodi:docname="ITangoConsole.svg"
- inkscape:version="0.48.1 r9760"
- version="1.1"
- id="svg2"
- height="512"
- width="512">
- <defs
- id="defs4">
- <linearGradient
- id="linearGradient990">
- <stop
- id="stop992"
- offset="0"
- style="stop-color:#d4d4d4;stop-opacity:1;" />
- <stop
- style="stop-color:#f6f6f6;stop-opacity:1;"
- offset="0.18783081"
- id="stop998" />
- <stop
- style="stop-color:#a7a7a7;stop-opacity:1;"
- offset="0.33046141"
- id="stop994" />
- <stop
- id="stop1026"
- offset="0.66523069"
- style="stop-color:#919191;stop-opacity:1;" />
- <stop
- style="stop-color:#868686;stop-opacity:1;"
- offset="0.83261538"
- id="stop1028" />
- <stop
- id="stop1032"
- offset="0.92357516"
- style="stop-color:#868686;stop-opacity:1;" />
- <stop
- id="stop1030"
- offset="0.96787697"
- style="stop-color:#aaaaaa;stop-opacity:1;" />
- <stop
- id="stop996"
- offset="1"
- style="stop-color:#c2c2c2;stop-opacity:1;" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- id="linearGradient1621">
- <stop
- style="stop-color:#d4d4d4;stop-opacity:1;"
- offset="0"
- id="stop1623" />
- <stop
- style="stop-color:#d4d4d4;stop-opacity:0;"
- offset="1"
- id="stop1625" />
- </linearGradient>
- <linearGradient
- id="linearGradient826">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop828" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0.69512194;"
- offset="1"
- id="stop830" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient826"
- id="linearGradient832"
- x1="105.70982"
- y1="518.53571"
- x2="757.14288"
- y2="248.53572"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.7551453,0,0,0.7551453,57.364381,318.43926)" />
- <style
- id="style1439"
- type="text/css">
-
- @font-face { font-family:"Inconsolata";src:url("#FontID0") format(svg)}
- .fil0 {fill:#1F1A17}
- .fil2 {fill:#006633}
- .fil1 {fill:#1F1A17}
- .fnt1 {font-weight:500;font-size:3.5278;font-family:'Inconsolata'}
- .fnt0 {font-weight:500;font-size:6.35;font-family:'Inconsolata'}
-
- </style>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient1621"
- id="linearGradient1631"
- gradientUnits="userSpaceOnUse"
- x1="390.46347"
- y1="712.64929"
- x2="389.88318"
- y2="764.16711"
- gradientTransform="matrix(0.7551453,0,0,0.7551453,57.364381,318.43922)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient990"
- id="linearGradient870"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.7551453,0,0,0.7551453,57.364381,318.43926)"
- x1="336.14798"
- y1="18.710255"
- x2="336.14798"
- y2="66.858391" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient990"
- id="linearGradient1012"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.7551453,0,0,0.7551453,57.364381,318.43926)"
- x1="291.68039"
- y1="511.74365"
- x2="291.68039"
- y2="564.10553" />
- <filter
- inkscape:collect="always"
- id="filter988">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="5.9071426"
- id="feGaussianBlur990" />
- </filter>
- <linearGradient
- id="linearGradient4689">
- <stop
- style="stop-color:#5a9fd4;stop-opacity:1"
- offset="0"
- id="stop4691" />
- <stop
- style="stop-color:#306998;stop-opacity:1"
- offset="1"
- id="stop4693" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4689"
- id="linearGradient4125"
- gradientUnits="userSpaceOnUse"
- x1="323.06018"
- y1="147.10051"
- x2="464.48874"
- y2="269.24338" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4689"
- id="linearGradient4127"
- gradientUnits="userSpaceOnUse"
- x1="323.06018"
- y1="147.10051"
- x2="464.48874"
- y2="269.24338" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4689"
- id="linearGradient4129"
- gradientUnits="userSpaceOnUse"
- x1="323.06018"
- y1="147.10051"
- x2="464.48874"
- y2="269.24338" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4689"
- id="linearGradient4131"
- gradientUnits="userSpaceOnUse"
- x1="323.06018"
- y1="147.10051"
- x2="464.48874"
- y2="269.24338" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4689"
- id="linearGradient4133"
- gradientUnits="userSpaceOnUse"
- x1="323.06018"
- y1="147.10051"
- x2="464.48874"
- y2="269.24338" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4689"
- id="linearGradient4135"
- gradientUnits="userSpaceOnUse"
- x1="323.06018"
- y1="147.10051"
- x2="464.48874"
- y2="269.24338" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4689"
- id="linearGradient4137"
- gradientUnits="userSpaceOnUse"
- x1="323.06018"
- y1="147.10051"
- x2="464.48874"
- y2="269.24338" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4689"
- id="linearGradient4139"
- gradientUnits="userSpaceOnUse"
- x1="486.50031"
- y1="184.54053"
- x2="496.16876"
- y2="248.36336" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4689"
- id="linearGradient4141"
- gradientUnits="userSpaceOnUse"
- x1="486.50031"
- y1="184.54053"
- x2="496.16876"
- y2="248.36336" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4689"
- id="linearGradient4143"
- gradientUnits="userSpaceOnUse"
- x1="485.7803"
- y1="185.98055"
- x2="496.88876"
- y2="249.08336" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4689"
- id="linearGradient4145"
- gradientUnits="userSpaceOnUse"
- x1="485.7803"
- y1="185.98055"
- x2="496.88876"
- y2="249.08336" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4689"
- id="linearGradient4147"
- gradientUnits="userSpaceOnUse"
- x1="484.3403"
- y1="182.38054"
- x2="495.44876"
- y2="243.32335" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4689"
- id="linearGradient4149"
- gradientUnits="userSpaceOnUse"
- x1="484.3403"
- y1="182.38054"
- x2="495.44876"
- y2="243.32335" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient4689"
- id="linearGradient4151"
- gradientUnits="userSpaceOnUse"
- x1="323.06018"
- y1="147.10051"
- x2="147.68851"
- y2="293.00339" />
- <filter
- id="filter3469"
- y="-0.25"
- height="1.5"
- inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
- inkscape:menu="Shadows and Glows"
- inkscape:label="Dark and Glow"
- color-interpolation-filters="sRGB">
- <feGaussianBlur
- id="feGaussianBlur3471"
- stdDeviation="5"
- result="result6" />
- <feComposite
- id="feComposite3473"
- in2="result6"
- result="result8"
- in="SourceGraphic"
- operator="atop" />
- <feComposite
- id="feComposite3475"
- in2="SourceAlpha"
- result="result9"
- operator="over"
- in="result8" />
- <feColorMatrix
- id="feColorMatrix3477"
- values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
- result="result10" />
- <feBlend
- id="feBlend3479"
- in2="result6"
- in="result10"
- mode="normal" />
- </filter>
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="0.98994949"
- inkscape:cx="327.50118"
- inkscape:cy="240.56031"
- inkscape:document-units="px"
- inkscape:current-layer="text109"
- showgrid="false"
- fit-margin-top="0"
- fit-margin-left="0"
- fit-margin-right="0"
- fit-margin-bottom="0"
- inkscape:window-width="1245"
- inkscape:window-height="675"
- inkscape:window-x="29"
- inkscape:window-y="25"
- inkscape:window-maximized="0" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Calque 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(-55.203036,-282.24337)">
- <rect
- style="opacity:0.41800005;color:#000000;fill:#020202;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter988);enable-background:accumulate"
- id="rect1032"
- width="628.57141"
- height="552.85712"
- x="76.46875"
- y="220.12053"
- rx="0"
- ry="0"
- transform="matrix(0.76259826,0,0,0.76259826,12.765793,164.57423)" />
- <rect
- y="332.22418"
- x="71.162964"
- height="415.55746"
- width="473.45871"
- id="rect1629"
- style="color:#000000;fill:url(#linearGradient1631);fill-opacity:1;fill-rule:nonzero;stroke:#5b5b5b;stroke-width:1.51029062;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- y="332.95441"
- x="71.774574"
- height="38.836063"
- width="472.50522"
- id="rect12"
- style="color:#000000;fill:url(#linearGradient870);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- id="rect797"
- d="m 71.774575,708.36947 472.505205,0 0,38.83606 -472.505205,0 z"
- style="color:#000000;fill:url(#linearGradient1012);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <rect
- style="color:#000000;fill:#0c212d;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- id="rect10"
- width="472.50522"
- height="338.7366"
- x="71.774574"
- y="369.63287" />
- <path
- style="opacity:0.231;color:#000000;fill:url(#linearGradient832);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- d="m 71.771204,369.62234 0,31.90891 0,1.86734 0,210.74249 C 185.0871,551.67384 349.48037,510.52371 535.90238,506.04065 c 2.79464,-0.0672 5.58165,-0.11401 8.37739,-0.16416 l 0,-102.4779 0,-1.86734 0,-31.90891 -472.508566,0 z"
- id="rect793"
- inkscape:connector-curvature="0" />
- <path
- inkscape:connector-curvature="0"
- id="path1030"
- d="m 71.774575,374.48737 472.505205,0 0,-4.85448 -472.505205,0 z"
- style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.75362319" />
- <path
- style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.76086957"
- d="m 71.774575,708.36947 472.505205,0 0,-4.85448 -472.505205,0 z"
- id="path1024"
- inkscape:connector-curvature="0" />
- <g
- id="text109"
- style="font-size:204.03166199px;font-weight:normal;fill:#ffffff;fill-rule:evenodd;font-family:Droid Sans Mono"
- transform="matrix(0.99206275,0,0,0.99206275,13.445202,330.71769)">
- <text
- xml:space="preserve"
- style="font-size:40.32003021px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter3469);font-family:Monospace;-inkscape-font-specification:Monospace"
- x="55.328968"
- y="243.28403"
- id="text3255"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan3257"
- x="55.328968"
- y="243.28403"
- style="font-size:131.0401001px;font-weight:bold;fill:#ffffff;-inkscape-font-specification:Monospace Bold">ITango</tspan></text>
- </g>
- </g>
-</svg>
diff --git a/src/boost/python/ipython/resource/database.png b/src/boost/python/ipython/resource/database.png
deleted file mode 100644
index ad598bb..0000000
Binary files a/src/boost/python/ipython/resource/database.png and /dev/null differ
diff --git a/src/boost/python/ipython/resource/device.png b/src/boost/python/ipython/resource/device.png
deleted file mode 100644
index 1b52f7d..0000000
Binary files a/src/boost/python/ipython/resource/device.png and /dev/null differ
diff --git a/src/boost/python/ipython/resource/motor.png b/src/boost/python/ipython/resource/motor.png
deleted file mode 100644
index abc5f20..0000000
Binary files a/src/boost/python/ipython/resource/motor.png and /dev/null differ
diff --git a/src/boost/python/ipython/resource/serial.png b/src/boost/python/ipython/resource/serial.png
deleted file mode 100644
index a7eef8d..0000000
Binary files a/src/boost/python/ipython/resource/serial.png and /dev/null differ
diff --git a/src/boost/python/ipython/resource/starter.png b/src/boost/python/ipython/resource/starter.png
deleted file mode 100644
index 2095e90..0000000
Binary files a/src/boost/python/ipython/resource/starter.png and /dev/null differ
diff --git a/winsetup.py b/winsetup.py
index 1f3a308..93f75ee 100644
--- a/winsetup.py
+++ b/winsetup.py
@@ -42,9 +42,7 @@ def main():
# temp_dir = osp.join(temp_base_dir, "PyTango", config_name)
if plat_name == 'x64':
plat_name = 'win-amd64'
-
- install_script = osp.join(winsetup_dir, 'scripts', 'pytango_winpostinstall.py')
- install_script = 'pytango_winpostinstall.py'
+
try:
cmd_line = '%s %s ' % (executable, setup_name)
cmd_line += 'build_py --force --no-compile ' \
@@ -57,15 +55,13 @@ def main():
cmd_line += 'bdist_msi --skip-build --target-version=%s ' \
'--bdist-dir=%s ' \
'--dist-dir=%s ' \
- '--install-script=%s ' \
- '--plat-name=%s ' % (ver, bdist_dir, dist_dir, install_script, plat_name)
+ '--plat-name=%s ' % (ver, bdist_dir, dist_dir, plat_name)
cmd_line += 'bdist_wininst --skip-build --target-version=%s ' \
'--bdist-dir=%s ' \
'--dist-dir=%s ' \
'--title="PyTango 8" ' \
'--bitmap="%s" ' \
- '--install-script=%s ' \
- '--plat-name=%s ' % (ver, bdist_dir, dist_dir, bitmap, install_script, plat_name)
+ '--plat-name=%s ' % (ver, bdist_dir, dist_dir, bitmap, plat_name)
os.system(cmd_line)
except:
print("Failed:")
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/pytango.git
More information about the debian-science-commits
mailing list