http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/doc/history.rst ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/doc/history.rst b/tools/bin/pythonSrc/pexpect-4.2/doc/history.rst new file mode 100644 index 0000000..f90d515 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/doc/history.rst @@ -0,0 +1,245 @@ +History +======= + +Releases +-------- + +Version 4.2 +``````````` + +* Change: When an ``env`` parameter is specified to the :class:`~.spawn` or + :class:`~.run` family of calls containing a value for ``PATH``, its value is + used to discover the target executable from a relative path, rather than the + current process's environment ``PATH``. This mirrors the behavior of + :func:`subprocess.Popen` in the standard library (:ghissue:`348`). + +* Regression: Re-introduce capability for :meth:`read_nonblocking` in class + :class:`fdspawn` as previously supported in version 3.3 (:ghissue:`359`). + +Version 4.0 +``````````` + +* Integration with :mod:`asyncio`: passing ``async=True`` to :meth:`~.spawn.expect`, + :meth:`~.spawn.expect_exact` or :meth:`~.spawn.expect_list` will make them return a + coroutine. You can get the result using ``yield from``, or wrap it in an + :class:`asyncio.Task`. This allows the event loop to do other things while + waiting for output that matches a pattern. +* Experimental support for Windows (with some caveats)âsee :ref:`windows`. +* Enhancement: allow method as callbacks of argument ``events`` for + :func:`pexpect.run` (:ghissue:`176`). +* It is now possible to call :meth:`~.spawn.wait` multiple times, or after a process + is already determined to be terminated without raising an exception + (:ghpull:`211`). +* New :class:`pexpect.spawn` keyword argument, ``dimensions=(rows, columns)`` + allows setting terminal screen dimensions before launching a program + (:ghissue:`122`). +* Fix regression that prevented executable, but unreadable files from + being found when not specified by absolute path -- such as + /usr/bin/sudo (:ghissue:`104`). +* Fixed regression when executing pexpect with some prior releases of + the multiprocessing module where stdin has been closed (:ghissue:`86`). + +Backwards incompatible changes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Deprecated ``pexpect.screen`` and ``pexpect.ANSI``. Please use other packages + such as `pyte <https://pypi.python.org/pypi/pyte>`__ to emulate a terminal. +* Removed the independent top-level modules (``pxssh fdpexpect FSM screen ANSI``) + which were installed alongside Pexpect. These were moved into the Pexpect + package in 3.0, but the old names were left as aliases. +* Child processes created by Pexpect no longer ignore SIGHUP by default: the + ``ignore_sighup`` parameter of :class:`pexpect.spawn` defaults to False. To + get the old behaviour, pass ``ignore_sighup=True``. + +Version 3.3 +``````````` + +* Added a mechanism to wrap REPLs, or shells, in an object which can conveniently + be used to send commands and wait for the output (:mod:`pexpect.replwrap`). +* Fixed issue where pexpect would attempt to execute a directory because + it has the 'execute' bit set (:ghissue:`37`). +* Removed the ``pexpect.psh`` module. This was never documented, and we found + no evidence that people use it. The new :mod:`pexpect.replwrap` module + provides a more flexible alternative. +* Fixed ``TypeError: got <type 'str'> ('\r\n') as pattern`` in :meth:`spawnu.readline` + method (:ghissue:`67`). +* Fixed issue where EOF was not correctly detected in :meth:`~.interact`, causing + a repeating loop of output on Linux, and blocking before EOF on BSD and + Solaris (:ghissue:`49`). +* Several Solaris (SmartOS) bugfixes, preventing :exc:`IOError` exceptions, especially + when used with cron(1) (:ghissue:`44`). +* Added new keyword argument ``echo=True`` for :class:`spawn`. On SVR4-like + systems, the method :meth:`~.isatty` will always return *False*: the child pty + does not appear as a terminal. Therefore, :meth:`~.setecho`, :meth:`~.getwinsize`, + :meth:`~.setwinsize`, and :meth:`~.waitnoecho` are not supported on those platforms. + +After this, we intend to start working on a bigger refactoring of the code, to +be released as Pexpect 4. There may be more bugfix 3.x releases, however. + +Version 3.2 +``````````` + +* Fix exception handling from :func:`select.select` on Python 2 (:ghpull:`38`). + This was accidentally broken in the previous release when it was fixed for + Python 3. +* Removed a workaround for ``TIOCSWINSZ`` on very old systems, which was causing + issues on some BSD systems (:ghpull:`40`). +* Fixed an issue with exception handling in :mod:`~pexpect.pxssh` (:ghpull:`43`) + +The documentation for :mod:`~pexpect.pxssh` was improved. + +Version 3.1 +``````````` + +* Fix an issue that prevented importing pexpect on Python 3 when ``sys.stdout`` + was reassigned (:ghissue:`30`). +* Improve prompt synchronisation in :mod:`~pexpect.pxssh` (:ghpull:`28`). +* Fix pickling exception instances (:ghpull:`34`). +* Fix handling exceptions from :func:`select.select` on Python 3 (:ghpull:`33`). + +The examples have also been cleaned up somewhat - this will continue in future +releases. + +Version 3.0 +``````````` + +The new major version number doesn't indicate any deliberate API incompatibility. +We have endeavoured to avoid breaking existing APIs. However, pexpect is under +new maintenance after a long dormancy, so some caution is warranted. + +* A new :ref:`unicode API <unicode>` was introduced. +* Python 3 is now supported, using a single codebase. +* Pexpect now requires at least Python 2.6 or 3.2. +* The modules other than pexpect, such as :mod:`pexpect.fdpexpect` and + :mod:`pexpect.pxssh`, were moved into the pexpect package. For now, wrapper + modules are installed to the old locations for backwards compatibility (e.g. + ``import pxssh`` will still work), but these will be removed at some point in + the future. +* Ignoring ``SIGHUP`` is now optional - thanks to Kimmo Parviainen-Jalanko for + the patch. + +We also now have `docs on ReadTheDocs <https://pexpect.readthedocs.io/>`_, +and `continuous integration on Travis CI <https://travis-ci.org/pexpect/pexpect>`_. + +Version 2.4 +``````````` + +* Fix a bug regarding making the pty the controlling terminal when the process + spawning it is not, actually, a terminal (such as from cron) + +Version 2.3 +``````````` + +* Fixed OSError exception when a pexpect object is cleaned up. Previously, you + might have seen this exception:: + + Exception exceptions.OSError: (10, 'No child processes') + in <bound method spawn.__del__ of <pexpect.spawn instance at 0xd248c>> ignored + + You should not see that anymore. Thanks to Michael Surette. +* Added support for buffering reads. This greatly improves speed when trying to + match long output from a child process. When you create an instance of the spawn + object you can then set a buffer size. For now you MUST do the following to turn + on buffering -- it may be on by default in future version:: + + child = pexpect.spawn ('my_command') + child.maxread=1000 # Sets buffer to 1000 characters. + +* I made a subtle change to the way TIMEOUT and EOF exceptions behave. + Previously you could either expect these states in which case pexpect + will not raise an exception, or you could just let pexpect raise an + exception when these states were encountered. If you expected the + states then the ``before`` property was set to everything before the + state was encountered, but if you let pexpect raise the exception then + ``before`` was not set. Now, the ``before`` property will get set either + way you choose to handle these states. +* The spawn object now provides iterators for a *file-like interface*. + This makes Pexpect a more complete file-like object. You can now write + code like this:: + + child = pexpect.spawn ('ls -l') + for line in child: + print line + +* write and writelines() no longer return a value. Use send() if you need that + functionality. I did this to make the Spawn object more closely match a + file-like object. +* Added the attribute ``exitstatus``. This will give the exit code returned + by the child process. This will be set to ``None`` while the child is still + alive. When ``isalive()`` returns 0 then ``exitstatus`` will be set. +* Made a few more tweaks to ``isalive()`` so that it will operate more + consistently on different platforms. Solaris is the most difficult to support. +* You can now put ``TIMEOUT`` in a list of expected patterns. This is just like + putting ``EOF`` in the pattern list. Expecting for a ``TIMEOUT`` may not be + used as often as ``EOF``, but this makes Pexpect more consistent. +* Thanks to a suggestion and sample code from Chad J. Schroeder I added the ability + for Pexpect to operate on a file descriptor that is already open. This means that + Pexpect can be used to control streams such as those from serial port devices. Now, + you just pass the integer file descriptor as the "command" when constructing a + spawn open. For example on a Linux box with a modem on ttyS1:: + + fd = os.open("/dev/ttyS1", os.O_RDWR|os.O_NONBLOCK|os.O_NOCTTY) + m = pexpect.spawn(fd) # Note integer fd is used instead of usual string. + m.send("+++") # Escape sequence + m.send("ATZ0\r") # Reset modem to profile 0 + rval = m.expect(["OK", "ERROR"]) + +* ``read()`` was renamed to ``read_nonblocking()``. Added new ``read()`` method + that matches file-like object interface. In general, you should not notice + the difference except that ``read()`` no longer allows you to directly set the + timeout value. I hope this will not effect any existing code. Switching to + ``read_nonblocking()`` should fix existing code. +* Changed the name of ``set_echo()`` to ``setecho()``. +* Changed the name of ``send_eof()`` to ``sendeof()``. +* Modified ``kill()`` so that it checks to make sure the pid ``isalive()``. +* modified ``spawn()`` (really called from ``__spawn()``) so that it does not + raise an expection if ``setwinsize()`` fails. Some platforms such as Cygwin + do not like setwinsize. This was a constant problem and since it is not a + critical feature I decided to just silence the error. Normally I don't like + to do that, but in this case I'm making an exception. +* Added a method ``close()`` that does what you think. It closes the file + descriptor of the child application. It makes no attempt to actually kill the + child or wait for its status. +* Add variables ``__version__`` and ``__revision__`` (from cvs) to the pexpect + modules. This is mainly helpful to me so that I can make sure that I'm testing + with the right version instead of one already installed. +* ``log_open()`` and ``log_close(`` have been removed. Now use ``setlog()``. + The ``setlog()`` method takes a file object. This is far more flexible than + the previous log method. Each time data is written to the file object it will + be flushed. To turn logging off simply call ``setlog()`` with None. +* renamed the ``isAlive()`` method to ``isalive()`` to match the more typical + naming style in Python. Also the technique used to detect child process + status has been drastically modified. Previously I did some funky stuff + with signals which caused indigestion in other Python modules on some + platforms. It was a big headache. It still is, but I think it works + better now. +* attribute ``matched`` renamed to ``after`` +* new attribute ``match`` +* The ``expect_eof()`` method is gone. You can now simply use the + ``expect()`` method to look for EOF. +* **Pexpect works on OS X**, but the nature of the quirks cause many of the + tests to fail. See bugs. (Incomplete Child Output). The problem is more + than minor, but Pexpect is still more than useful for most tasks. +* **Solaris**: For some reason, the *second* time a pty file descriptor is created and + deleted it never gets returned for use. It does not effect the first time + or the third time or any time after that. It's only the second time. This + is weird... This could be a file descriptor leak, or it could be some + peculiarity of how Solaris recycles them. I thought it was a UNIX requirement + for the OS to give you the lowest available filedescriptor number. In any case, + this should not be a problem unless you create hundreds of pexpect instances... + It may also be a pty module bug. + + +Moves and forks +--------------- + +* Pexpect development used to be hosted on Sourceforge. +* In 2011, Thomas Kluyver forked pexpect as 'pexpect-u', to support + Python 3. He later decided he had taken the wrong approach with this. +* In 2012, Noah Spurrier, the original author of Pexpect, moved the + project to Github, but was still too busy to develop it much. +* In 2013, Thomas Kluyver and Jeff Quast forked Pexpect again, intending + to call the new fork Pexpected. Noah Spurrier agreed to let them use + the name Pexpect, so Pexpect versions 3 and above are based on this + fork, which now lives `here on Github <https://github.com/pexpect/pexpect>`_. +
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/doc/index.rst ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/doc/index.rst b/tools/bin/pythonSrc/pexpect-4.2/doc/index.rst new file mode 100644 index 0000000..0bcf862 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/doc/index.rst @@ -0,0 +1,50 @@ +Pexpect version |version| +========================= + +.. image:: https://travis-ci.org/pexpect/pexpect.png?branch=master + :target: https://travis-ci.org/pexpect/pexpect + :align: right + :alt: Build status + +Pexpect makes Python a better tool for controlling other +applications. + +Pexpect is a pure Python module for spawning child applications; +controlling them; and responding to expected patterns in their output. +Pexpect works like Don Libes' Expect. Pexpect allows your script to +spawn a child application and control it as if a human were typing +commands. + +Pexpect can be used for automating interactive applications such as +ssh, ftp, passwd, telnet, etc. It can be used to a automate setup +scripts for duplicating software package installations on different +servers. It can be used for automated software testing. Pexpect is in +the spirit of Don Libes' Expect, but Pexpect is pure Python. Unlike +other Expect-like modules for Python, Pexpect does not require TCL or +Expect nor does it require C extensions to be compiled. It should work +on any platform that supports the standard Python pty module. The +Pexpect interface was designed to be easy to use. + +Contents: + +.. toctree:: + :maxdepth: 2 + + install + overview + api/index + examples + FAQ + commonissues + history + +Pexpect is developed `on Github <http://github.com/pexpect/pexpect>`_. Please +report `issues <https://github.com/pexpect/pexpect/issues>`_ there as well. + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/doc/install.rst ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/doc/install.rst b/tools/bin/pythonSrc/pexpect-4.2/doc/install.rst new file mode 100644 index 0000000..6f7e36a --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/doc/install.rst @@ -0,0 +1,20 @@ +Installation +============ + +Pexpect is on PyPI, and can be installed with standard tools:: + + pip install pexpect + +Or:: + + easy_install pexpect + +Requirements +------------ + +This version of Pexpect requires Python 3.3 or above, or Python 2.7. + +As of version 4.0, Pexpect can be used on Windows and POSIX systems. However, +:class:`pexpect.spawn` and :func:`pexpect.run` are only available on POSIX, +where the :mod:`pty` module is present in the standard library. See +:ref:`windows` for more information. http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/doc/make.bat ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/doc/make.bat b/tools/bin/pythonSrc/pexpect-4.2/doc/make.bat new file mode 100644 index 0000000..448f147 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/doc/make.bat @@ -0,0 +1,190 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^<target^>` where ^<target^> is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Pexpect.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Pexpect.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/doc/overview.rst ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/doc/overview.rst b/tools/bin/pythonSrc/pexpect-4.2/doc/overview.rst new file mode 100644 index 0000000..d394ef1 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/doc/overview.rst @@ -0,0 +1,257 @@ +API Overview +============ + +Pexpect can be used for automating interactive applications such as ssh, ftp, +mencoder, passwd, etc. The Pexpect interface was designed to be easy to use. + +Here is an example of Pexpect in action:: + + # This connects to the openbsd ftp site and + # downloads the recursive directory listing. + import pexpect + child = pexpect.spawn('ftp ftp.openbsd.org') + child.expect('Name .*: ') + child.sendline('anonymous') + child.expect('Password:') + child.sendline('[email protected]') + child.expect('ftp> ') + child.sendline('lcd /tmp') + child.expect('ftp> ') + child.sendline('cd pub/OpenBSD') + child.expect('ftp> ') + child.sendline('get README') + child.expect('ftp> ') + child.sendline('bye') + +Obviously you could write an ftp client using Python's own :mod:`ftplib` module, +but this is just a demonstration. You can use this technique with any application. +This is especially handy if you are writing automated test tools. + +There are two important methods in Pexpect -- :meth:`~pexpect.spawn.expect` and +:meth:`~pexpect.spawn.send` (or :meth:`~pexpect.spawn.sendline` which is +like :meth:`~pexpect.spawn.send` with a linefeed). The :meth:`~pexpect.spawn.expect` +method waits for the child application to return a given string. The string you +specify is a regular expression, so you can match complicated patterns. The +:meth:`~pexpect.spawn.send` method writes a string to the child application. +From the child's point of view it looks just like someone typed the text from a +terminal. After each call to :meth:`~pexpect.spawn.expect` the ``before`` and ``after`` +properties will be set to the text printed by child application. The ``before`` +property will contain all text up to the expected string pattern. The ``after`` +string will contain the text that was matched by the expected pattern. +The match property is set to the `re match object <http://docs.python.org/3/library/re#match-objects>`_. + +An example of Pexpect in action may make things more clear. This example uses +ftp to login to the OpenBSD site; list files in a directory; and then pass +interactive control of the ftp session to the human user:: + + import pexpect + child = pexpect.spawn ('ftp ftp.openbsd.org') + child.expect ('Name .*: ') + child.sendline ('anonymous') + child.expect ('Password:') + child.sendline ('[email protected]') + child.expect ('ftp> ') + child.sendline ('ls /pub/OpenBSD/') + child.expect ('ftp> ') + print child.before # Print the result of the ls command. + child.interact() # Give control of the child to the user. + +Special EOF and TIMEOUT patterns +-------------------------------- + +There are two special patterns to match the End Of File (:class:`~pexpect.EOF`) +or a Timeout condition (:class:`~pexpect.TIMEOUT`). You can pass these +patterns to :meth:`~pexpect.spawn.expect`. These patterns are not regular +expressions. Use them like predefined constants. + +If the child has died and you have read all the child's output then ordinarily +:meth:`~pexpect.spawn.expect` will raise an :class:`~pexpect.EOF` exception. +You can read everything up to the EOF without generating an exception by using +the EOF pattern expect. In this case everything the child has output will be +available in the ``before`` property. + +The pattern given to :meth:`~pexpect.spawn.expect` may be a regular expression +or it may also be a list of regular expressions. This allows you to match +multiple optional responses. The :meth:`~pexpect.spawn.expect` method returns +the index of the pattern that was matched. For example, say you wanted to login +to a server. After entering a password you could get various responses from the +server -- your password could be rejected; or you could be allowed in and asked +for your terminal type; or you could be let right in and given a command prompt. +The following code fragment gives an example of this:: + + child.expect('password:') + child.sendline(my_secret_password) + # We expect any of these three patterns... + i = child.expect (['Permission denied', 'Terminal type', '[#\$] ']) + if i==0: + print('Permission denied on host. Can\'t login') + child.kill(0) + elif i==1: + print('Login OK... need to send terminal type.') + child.sendline('vt100') + child.expect('[#\$] ') + elif i==2: + print('Login OK.') + print('Shell command prompt', child.after) + +If nothing matches an expected pattern then :meth:`~pexpect.spawn.expect` will +eventually raise a :class:`~pexpect.TIMEOUT` exception. The default time is 30 +seconds, but you can change this by passing a timeout argument to +:meth:`~pexpect.spawn.expect`:: + + # Wait no more than 2 minutes (120 seconds) for password prompt. + child.expect('password:', timeout=120) + +Find the end of line -- CR/LF conventions +----------------------------------------- + +Pexpect matches regular expressions a little differently than what you might be +used to. + +The :regexp:`$` pattern for end of line match is useless. The :regexp:`$` +matches the end of string, but Pexpect reads from the child one character at a +time, so each character looks like the end of a line. Pexpect can't do a +look-ahead into the child's output stream. In general you would have this +situation when using regular expressions with any stream. + +.. note:: + + Pexpect does have an internal buffer, so reads are faster than one character + at a time, but from the user's perspective the regex patterns test happens + one character at a time. + +The best way to match the end of a line is to look for the newline: ``"\r\n"`` +(CR/LF). Yes, that does appear to be DOS-style. It may surprise some UNIX people +to learn that terminal TTY device drivers (dumb, vt100, ANSI, xterm, etc.) all +use the CR/LF combination to signify the end of line. Pexpect uses a Pseudo-TTY +device to talk to the child application, so when the child app prints ``"\n"`` +you actually see ``"\r\n"``. + +UNIX uses just linefeeds to end lines of text, but not when it comes to TTY +devices! TTY devices are more like the Windows world. Each line of text ends +with a CR/LF combination. When you intercept data from a UNIX command from a +TTY device you will find that the TTY device outputs a CR/LF combination. A +UNIX command may only write a linefeed (``\n``), but the TTY device driver +converts it to CR/LF. This means that your terminal will see lines end with +CR/LF (hex ``0D 0A``). Since Pexpect emulates a terminal, to match ends of +lines you have to expect the CR/LF combination:: + + child.expect('\r\n') + +If you just need to skip past a new line then ``expect('\n')`` by itself will +work, but if you are expecting a specific pattern before the end of line then +you need to explicitly look for the ``\r``. For example the following expects a +word at the end of a line:: + + child.expect('\w+\r\n') + +But the following would both fail:: + + child.expect('\w+\n') + +And as explained before, trying to use :regexp:`$` to match the end of line +would not work either:: + + child.expect ('\w+$') + +So if you need to explicitly look for the END OF LINE, you want to look for the +CR/LF combination -- not just the LF and not the $ pattern. + +This problem is not limited to Pexpect. This problem happens any time you try +to perform a regular expression match on a stream. Regular expressions need to +look ahead. With a stream it is hard to look ahead because the process +generating the stream may not be finished. There is no way to know if the +process has paused momentarily or is finished and waiting for you. Pexpect must +implicitly always do a NON greedy match (minimal) at the end of a input. + +Pexpect compiles all regular expressions with the :data:`re.DOTALL` flag. +With the :data:`~re.DOTALL` flag, a ``"."`` will match a newline. + +Beware of + and * at the end of patterns +---------------------------------------- + +Remember that any time you try to match a pattern that needs look-ahead that +you will always get a minimal match (non greedy). For example, the following +will always return just one character:: + + child.expect ('.+') + +This example will match successfully, but will always return no characters:: + + child.expect ('.*') + +Generally any star * expression will match as little as possible. + +One thing you can do is to try to force a non-ambiguous character at the end of +your :regexp:`\\d+` pattern. Expect that character to delimit the string. For +example, you might try making the end of your pattern be :regexp:`\\D+` instead +of :regexp:`\\D*`. Number digits alone would not satisfy the :regexp:`(\\d+)\\D+` +pattern. You would need some numbers and at least one non-number at the end. + + +Debugging +--------- + +If you get the string value of a :class:`pexpect.spawn` object you will get lots +of useful debugging information. For debugging it's very useful to use the +following pattern:: + + try: + i = child.expect ([pattern1, pattern2, pattern3, etc]) + except: + print("Exception was thrown") + print("debug information:") + print(str(child)) + +It is also useful to log the child's input and out to a file or the screen. The +following will turn on logging and send output to stdout (the screen):: + + child = pexpect.spawn(foo) + child.logfile = sys.stdout + +Exceptions +---------- + +:class:`~pexpect.EOF` + +Note that two flavors of EOF Exception may be thrown. They are virtually +identical except for the message string. For practical purposes you should have +no need to distinguish between them, but they do give a little extra information +about what type of platform you are running. The two messages are: + +- "End Of File (EOF) in read(). Exception style platform." +- "End Of File (EOF) in read(). Empty string style platform." + +Some UNIX platforms will throw an exception when you try to read from a file +descriptor in the EOF state. Other UNIX platforms instead quietly return an +empty string to indicate that the EOF state has been reached. + +If you wish to read up to the end of the child's output without generating an +:class:`~pexpect.EOF` exception then use the ``expect(pexpect.EOF)`` method. + +:class:`~pexpect.TIMEOUT` + +The :meth:`~pexpect.spawn.expect` and :meth:`~pexpect.spawn.read` methods will +also timeout if the child does not generate any output for a given amount of +time. If this happens they will raise a :class:`~pexpect.TIMEOUT` exception. +You can have these methods ignore timeout and block indefinitely by passing +``None`` for the timeout parameter:: + + child.expect(pexpect.EOF, timeout=None) + +.. _windows: + +Pexpect on Windows +------------------ + +.. versionadded:: 4.0 + Windows support + +Pexpect can be used on Windows to wait for a pattern to be produced by a child +process, using :class:`pexpect.popen_spawn.PopenSpawn`, or a file descriptor, +using :class:`pexpect.fdpexpect.fdspawn`. This should be considered experimental +for now. + +:class:`pexpect.spawn` and :func:`pexpect.run` are *not* available on Windows, +as they rely on Unix pseudoterminals (ptys). Cross platform code must not use +these. http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/doc/requirements.txt ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/doc/requirements.txt b/tools/bin/pythonSrc/pexpect-4.2/doc/requirements.txt new file mode 100644 index 0000000..57ebb2d --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/doc/requirements.txt @@ -0,0 +1 @@ +ptyprocess http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/doc/sphinxext/github.py ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/doc/sphinxext/github.py b/tools/bin/pythonSrc/pexpect-4.2/doc/sphinxext/github.py new file mode 100644 index 0000000..519e146 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/doc/sphinxext/github.py @@ -0,0 +1,155 @@ +"""Define text roles for GitHub + +* ghissue - Issue +* ghpull - Pull Request +* ghuser - User + +Adapted from bitbucket example here: +https://bitbucket.org/birkenfeld/sphinx-contrib/src/tip/bitbucket/sphinxcontrib/bitbucket.py + +Authors +------- + +* Doug Hellmann +* Min RK +""" +# +# Original Copyright (c) 2010 Doug Hellmann. All rights reserved. +# + +from docutils import nodes, utils +from docutils.parsers.rst.roles import set_classes + +def make_link_node(rawtext, app, type, slug, options): + """Create a link to a github resource. + + :param rawtext: Text being replaced with link node. + :param app: Sphinx application context + :param type: Link type (issues, changeset, etc.) + :param slug: ID of the thing to link to + :param options: Options dictionary passed to role func. + """ + + try: + base = app.config.github_project_url + if not base: + raise AttributeError + if not base.endswith('/'): + base += '/' + except AttributeError as err: + raise ValueError('github_project_url configuration value is not set (%s)' % str(err)) + + ref = base + type + '/' + slug + '/' + set_classes(options) + prefix = "#" + if type == 'pull': + prefix = "PR " + prefix + node = nodes.reference(rawtext, prefix + utils.unescape(slug), refuri=ref, + **options) + return node + +def ghissue_role(name, rawtext, text, lineno, inliner, options={}, content=[]): + """Link to a GitHub issue. + + Returns 2 part tuple containing list of nodes to insert into the + document and a list of system messages. Both are allowed to be + empty. + + :param name: The role name used in the document. + :param rawtext: The entire markup snippet, with role. + :param text: The text marked with the role. + :param lineno: The line number where rawtext appears in the input. + :param inliner: The inliner instance that called us. + :param options: Directive options for customization. + :param content: The directive content for customization. + """ + + try: + issue_num = int(text) + if issue_num <= 0: + raise ValueError + except ValueError: + msg = inliner.reporter.error( + 'GitHub issue number must be a number greater than or equal to 1; ' + '"%s" is invalid.' % text, line=lineno) + prb = inliner.problematic(rawtext, rawtext, msg) + return [prb], [msg] + app = inliner.document.settings.env.app + #app.info('issue %r' % text) + if 'pull' in name.lower(): + category = 'pull' + elif 'issue' in name.lower(): + category = 'issues' + else: + msg = inliner.reporter.error( + 'GitHub roles include "ghpull" and "ghissue", ' + '"%s" is invalid.' % name, line=lineno) + prb = inliner.problematic(rawtext, rawtext, msg) + return [prb], [msg] + node = make_link_node(rawtext, app, category, str(issue_num), options) + return [node], [] + +def ghuser_role(name, rawtext, text, lineno, inliner, options={}, content=[]): + """Link to a GitHub user. + + Returns 2 part tuple containing list of nodes to insert into the + document and a list of system messages. Both are allowed to be + empty. + + :param name: The role name used in the document. + :param rawtext: The entire markup snippet, with role. + :param text: The text marked with the role. + :param lineno: The line number where rawtext appears in the input. + :param inliner: The inliner instance that called us. + :param options: Directive options for customization. + :param content: The directive content for customization. + """ + app = inliner.document.settings.env.app + #app.info('user link %r' % text) + ref = 'https://www.github.com/' + text + node = nodes.reference(rawtext, text, refuri=ref, **options) + return [node], [] + +def ghcommit_role(name, rawtext, text, lineno, inliner, options={}, content=[]): + """Link to a GitHub commit. + + Returns 2 part tuple containing list of nodes to insert into the + document and a list of system messages. Both are allowed to be + empty. + + :param name: The role name used in the document. + :param rawtext: The entire markup snippet, with role. + :param text: The text marked with the role. + :param lineno: The line number where rawtext appears in the input. + :param inliner: The inliner instance that called us. + :param options: Directive options for customization. + :param content: The directive content for customization. + """ + app = inliner.document.settings.env.app + #app.info('user link %r' % text) + try: + base = app.config.github_project_url + if not base: + raise AttributeError + if not base.endswith('/'): + base += '/' + except AttributeError as err: + raise ValueError('github_project_url configuration value is not set (%s)' % str(err)) + + ref = base + text + node = nodes.reference(rawtext, text[:6], refuri=ref, **options) + return [node], [] + + +def setup(app): + """Install the plugin. + + :param app: Sphinx application context. + """ + app.info('Initializing GitHub plugin') + app.add_role('ghissue', ghissue_role) + app.add_role('ghpull', ghissue_role) + app.add_role('ghuser', ghuser_role) + app.add_role('ghcommit', ghcommit_role) + app.add_config_value('github_project_url', None, 'env') + return http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/README ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/README b/tools/bin/pythonSrc/pexpect-4.2/examples/README new file mode 100644 index 0000000..be21e96 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/README @@ -0,0 +1,89 @@ +This directory contains scripts that give examples of using Pexpect. + +hive.py + This script creates SSH connections to a list of hosts that + you provide. Then you are given a command line prompt. Each + shell command that you enter is sent to all the hosts. The + response from each host is collected and printed. For example, + you could connect to a dozen different machines and reboot + them all at once. + +script.py + This implements a command similar to the classic BSD "script" command. + This will start a subshell and log all input and output to a file. + This demonstrates the interact() method of Pexpect. + +fix_cvs_files.py + This is for cleaning up binary files improperly added to + CVS. This script scans the given path to find binary files; + checks with CVS to see if the sticky options are set to -kb; + finally if sticky options are not -kb then uses 'cvs admin' + to set the -kb option. + +ftp.py + This demonstrates an FTP "bookmark". + This connects to an ftp site; does a few ftp commands; and then gives the user + interactive control over the session. In this case the "bookmark" is to a + directory on the OpenBSD ftp server. It puts you in the i386 packages + directory. You can easily modify this for other sites. + This demonstrates the interact() method of Pexpect. + +monitor.py + This runs a sequence of system status commands on a remote host using SSH. + It runs a simple system checks such as uptime and free to monitor + the state of the remote host. + +passmass.py + This will login to a list of hosts and change the password of the + given user. This demonstrates scripting logins; although, you could + more easily do this using the pxssh subclass of Pexpect. + See also the "hive.py" example script for a more general example + of scripting a collection of servers. + +python.py + This starts the python interpreter and prints the greeting message backwards. + It then gives the user interactive control of Python. It's pretty useless! + +rippy.py + This is a wizard for mencoder. It greatly simplifies the process of + ripping a DVD to mpeg4 format (XviD, DivX). It can transcode from any + video file to another. It has options for resampling the audio stream; + removing interlace artifacts, fitting to a target file size, etc. + There are lots of options, but the process is simple and easy to use. + +sshls.py + This lists a directory on a remote machine. + +ssh_tunnel.py + This starts an SSH tunnel to a remote machine. It monitors the connection + and restarts the tunnel if it goes down. + +uptime.py + This will run the uptime command and parse the output into python variables. + This demonstrates using a single regular expression to match the output + of a command and capturing different variable in match groups. + The regular expression takes into account a wide variety of different + formats for uptime output. + +df.py + This collects filesystem capacity info using the 'df' command. + Tuples of filesystem name and percentage are stored in a list. + A simple report is printed. Filesystems over 95% capacity are highlighted. + +PEXPECT LICENSE + + This license is approved by the OSI and FSF as GPL-compatible. + http://opensource.org/licenses/isc-license.txt + + Copyright (c) 2012, Noah Spurrier <[email protected]> + PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY + PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE + COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/astat.py ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/astat.py b/tools/bin/pythonSrc/pexpect-4.2/examples/astat.py new file mode 100755 index 0000000..a083fe1 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/astat.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python + +'''This runs Apache Status on the remote host and returns the number of requests per second. + +./astat.py [-s server_hostname] [-u username] [-p password] + -s : hostname of the remote server to login to. + -u : username to user for login. + -p : Password to user for login. + +Example: + This will print information about the given host: + ./astat.py -s www.example.com -u mylogin -p mypassword + +PEXPECT LICENSE + + This license is approved by the OSI and FSF as GPL-compatible. + http://opensource.org/licenses/isc-license.txt + + Copyright (c) 2012, Noah Spurrier <[email protected]> + PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY + PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE + COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +''' + +from __future__ import print_function + +from __future__ import absolute_import + +import os +import sys +import getopt +import getpass +import pxssh + + +try: + raw_input +except NameError: + raw_input = input + + +def exit_with_usage(): + + print(globals()['__doc__']) + os._exit(1) + + +def main(): + + ###################################################################### + ## Parse the options, arguments, get ready, etc. + ###################################################################### + try: + optlist, args = getopt.getopt(sys.argv[1:], 'h?s:u:p:', ['help','h','?']) + except Exception as e: + print(str(e)) + exit_with_usage() + options = dict(optlist) + if len(args) > 1: + exit_with_usage() + + if [elem for elem in options if elem in ['-h','--h','-?','--?','--help']]: + print("Help:") + exit_with_usage() + + if '-s' in options: + hostname = options['-s'] + else: + hostname = raw_input('hostname: ') + if '-u' in options: + username = options['-u'] + else: + username = raw_input('username: ') + if '-p' in options: + password = options['-p'] + else: + password = getpass.getpass('password: ') + + # + # Login via SSH + # + p = pxssh.pxssh() + p.login(hostname, username, password) + p.sendline('apachectl status') + p.expect('([0-9]+\.[0-9]+)\s*requests/sec') + requests_per_second = p.match.groups()[0] + p.logout() + print(requests_per_second) + +if __name__ == "__main__": + main() http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/cgishell.cgi ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/cgishell.cgi b/tools/bin/pythonSrc/pexpect-4.2/examples/cgishell.cgi new file mode 100755 index 0000000..23bef5f --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/cgishell.cgi @@ -0,0 +1,766 @@ +#!/usr/bin/python +##!/usr/bin/env python +"""CGI shell server + +This exposes a shell terminal on a web page. +It uses AJAX to send keys and receive screen updates. +The client web browser needs nothing but CSS and Javascript. + + --hostname : sets the remote host name to open an ssh connection to. + --username : sets the user name to login with + --password : (optional) sets the password to login with + --port : set the local port for the server to listen on + --watch : show the virtual screen after each client request + +This project is probably not the most security concious thing I've ever built. +This should be considered an experimental tool -- at best. +""" + +from __future__ import absolute_import +from __future__ import print_function + +import sys,os +sys.path.insert (0,os.getcwd()) # let local modules precede any installed modules +import socket, random, string, traceback, cgi, time, getopt, getpass, threading, resource, signal +import pxssh, pexpect, ANSI + +def exit_with_usage(exit_code=1): + print(globals()['__doc__']) + os._exit(exit_code) + +def client (command, host='localhost', port=-1): + """This sends a request to the server and returns the response. + If port <= 0 then host is assumed to be the filename of a Unix domain socket. + If port > 0 then host is an inet hostname. + """ + if port <= 0: + s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + s.connect(host) + else: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.connect((host, port)) + s.send(command) + data = s.recv (2500) + s.close() + return data + +def server (hostname, username, password, socket_filename='/tmp/server_sock', daemon_mode = True, verbose=False): + """This starts and services requests from a client. + If daemon_mode is True then this forks off a separate daemon process and returns the daemon's pid. + If daemon_mode is False then this does not return until the server is done. + """ + if daemon_mode: + mypid_name = '/tmp/%d.pid' % os.getpid() + daemon_pid = daemonize(daemon_pid_filename=mypid_name) + time.sleep(1) + if daemon_pid != 0: + os.unlink(mypid_name) + return daemon_pid + + virtual_screen = ANSI.ANSI (24,80) + child = pxssh.pxssh() + try: + child.login (hostname, username, password, login_naked=True) + except: + return + if verbose: print('login OK') + virtual_screen.write (child.before) + virtual_screen.write (child.after) + + if os.path.exists(socket_filename): os.remove(socket_filename) + s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + s.bind(socket_filename) + os.chmod(socket_filename, 0o777) + if verbose: print('Listen') + s.listen(1) + + r = roller (endless_poll, (child, child.PROMPT, virtual_screen)) + r.start() + if verbose: print("started screen-poll-updater in background thread") + sys.stdout.flush() + try: + while True: + conn, addr = s.accept() + if verbose: print('Connected by', addr) + data = conn.recv(1024) + request = data.split(' ', 1) + if len(request)>1: + cmd = request[0].strip() + arg = request[1].strip() + else: + cmd = request[0].strip() + arg = '' + + if cmd == 'exit': + r.cancel() + break + elif cmd == 'sendline': + child.sendline (arg) + time.sleep(0.1) + shell_window = str(virtual_screen) + elif cmd == 'send' or cmd=='xsend': + if cmd=='xsend': + arg = arg.decode("hex") + child.send (arg) + time.sleep(0.1) + shell_window = str(virtual_screen) + elif cmd == 'cursor': + shell_window = '%x,%x' % (virtual_screen.cur_r, virtual_screen.cur_c) + elif cmd == 'refresh': + shell_window = str(virtual_screen) + elif cmd == 'hash': + shell_window = str(hash(str(virtual_screen))) + + response = [] + response.append (shell_window) + if verbose: print('\n'.join(response)) + sent = conn.send('\n'.join(response)) + if sent < len (response): + if verbose: print("Sent is too short. Some data was cut off.") + conn.close() + except e: + pass + r.cancel() + if verbose: print("cleaning up socket") + s.close() + if os.path.exists(socket_filename): os.remove(socket_filename) + if verbose: print("server done!") + +class roller (threading.Thread): + """This class continuously loops a function in a thread. + This is basically a thin layer around Thread with a + while loop and a cancel. + """ + def __init__(self, function, args=[], kwargs={}): + threading.Thread.__init__(self) + self.function = function + self.args = args + self.kwargs = kwargs + self.finished = threading.Event() + def cancel(self): + """Stop the roller.""" + self.finished.set() + def run(self): + while not self.finished.isSet(): + self.function(*self.args, **self.kwargs) + +def endless_poll (child, prompt, screen, refresh_timeout=0.1): + """This keeps the screen updated with the output of the child. + This will be run in a separate thread. See roller class. + """ + #child.logfile_read = screen + try: + s = child.read_nonblocking(4000, 0.1) + screen.write(s) + except: + pass + +def daemonize (stdin=None, stdout=None, stderr=None, daemon_pid_filename=None): + """This runs the current process in the background as a daemon. + The arguments stdin, stdout, stderr allow you to set the filename that the daemon reads and writes to. + If they are set to None then all stdio for the daemon will be directed to /dev/null. + If daemon_pid_filename is set then the pid of the daemon will be written to it as plain text + and the pid will be returned. If daemon_pid_filename is None then this will return None. + """ + UMASK = 0 + WORKINGDIR = "/" + MAXFD = 1024 + + # The stdio file descriptors are redirected to /dev/null by default. + if hasattr(os, "devnull"): + DEVNULL = os.devnull + else: + DEVNULL = "/dev/null" + if stdin is None: stdin = DEVNULL + if stdout is None: stdout = DEVNULL + if stderr is None: stderr = DEVNULL + + try: + pid = os.fork() # fork first child + except OSError as e: + raise Exception("%s [%d]" % (e.strerror, e.errno)) + + if pid != 0: + os.waitpid(pid,0) + if daemon_pid_filename is not None: + daemon_pid = int(file(daemon_pid_filename,'r').read()) + return daemon_pid + else: + return None + + # first child + os.setsid() + signal.signal(signal.SIGHUP, signal.SIG_IGN) + + try: + pid = os.fork() # fork second child + except OSError as e: + raise Exception("%s [%d]" % (e.strerror, e.errno)) + + if pid != 0: + if daemon_pid_filename is not None: + file(daemon_pid_filename,'w').write(str(pid)) + os._exit(0) # exit parent (the first child) of the second child. + + # second child + os.chdir(WORKINGDIR) + os.umask(UMASK) + + maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] + if maxfd == resource.RLIM_INFINITY: + maxfd = MAXFD + + # close all file descriptors + for fd in range(0, maxfd): + try: + os.close(fd) + except OSError: # fd wasn't open to begin with (ignored) + pass + + os.open (DEVNULL, os.O_RDWR) # standard input + + # redirect standard file descriptors + si = open(stdin, 'r') + so = open(stdout, 'a+') + se = open(stderr, 'a+', 0) + os.dup2(si.fileno(), sys.stdin.fileno()) + os.dup2(so.fileno(), sys.stdout.fileno()) + os.dup2(se.fileno(), sys.stderr.fileno()) + + return 0 + +def client_cgi (): + """This handles the request if this script was called as a cgi. + """ + sys.stderr = sys.stdout + ajax_mode = False + TITLE="Shell" + SHELL_OUTPUT="" + SID="NOT" + print("Content-type: text/html;charset=utf-8\r\n") + try: + form = cgi.FieldStorage() + if 'ajax' in form: + ajax_mode = True + ajax_cmd = form['ajax'].value + SID=form['sid'].value + if ajax_cmd == 'send': + command = 'xsend' + arg = form['arg'].value.encode('hex') + result = client (command + ' ' + arg, '/tmp/'+SID) + print(result) + elif ajax_cmd == 'refresh': + command = 'refresh' + result = client (command, '/tmp/'+SID) + print(result) + elif ajax_cmd == 'cursor': + command = 'cursor' + result = client (command, '/tmp/'+SID) + print(result) + elif ajax_cmd == 'exit': + command = 'exit' + result = client (command, '/tmp/'+SID) + print(result) + elif ajax_cmd == 'hash': + command = 'hash' + result = client (command, '/tmp/'+SID) + print(result) + elif 'sid' not in form: + SID=random_sid() + print(LOGIN_HTML % locals()); + else: + SID=form['sid'].value + if 'start_server' in form: + USERNAME = form['username'].value + PASSWORD = form['password'].value + dpid = server ('127.0.0.1', USERNAME, PASSWORD, '/tmp/'+SID) + SHELL_OUTPUT="daemon pid: " + str(dpid) + else: + if 'cli' in form: + command = 'sendline ' + form['cli'].value + else: + command = 'sendline' + SHELL_OUTPUT = client (command, '/tmp/'+SID) + print(CGISH_HTML % locals()) + except: + tb_dump = traceback.format_exc() + if ajax_mode: + print(str(tb_dump)) + else: + SHELL_OUTPUT=str(tb_dump) + print(CGISH_HTML % locals()) + +def server_cli(): + """This is the command line interface to starting the server. + This handles things if the script was not called as a CGI + (if you run it from the command line). + """ + try: + optlist, args = getopt.getopt(sys.argv[1:], 'h?d', ['help','h','?', 'hostname=', 'username=', 'password=', 'port=', 'watch']) + except Exception as e: + print(str(e)) + exit_with_usage() + + command_line_options = dict(optlist) + options = dict(optlist) + # There are a million ways to cry for help. These are but a few of them. + if [elem for elem in command_line_options if elem in ['-h','--h','-?','--?','--help']]: + exit_with_usage(0) + + hostname = "127.0.0.1" + #port = 1664 + username = os.getenv('USER') + password = "" + daemon_mode = False + if '-d' in options: + daemon_mode = True + if '--watch' in options: + watch_mode = True + else: + watch_mode = False + if '--hostname' in options: + hostname = options['--hostname'] + if '--port' in options: + port = int(options['--port']) + if '--username' in options: + username = options['--username'] + if '--password' in options: + password = options['--password'] + else: + password = getpass.getpass('password: ') + + server (hostname, username, password, '/tmp/mysock', daemon_mode) + +def random_sid (): + a=random.randint(0,65535) + b=random.randint(0,65535) + return '%04x%04x.sid' % (a,b) + +def parse_host_connect_string (hcs): + """This parses a host connection string in the form + username:password@hostname:port. All fields are options expcet hostname. A + dictionary is returned with all four keys. Keys that were not included are + set to empty strings ''. Note that if your password has the '@' character + then you must backslash escape it. + """ + if '@' in hcs: + p = re.compile (r'(?P<username>[^@:]*)(:?)(?P<password>.*)(?!\\)@(?P<hostname>[^:]*):?(?P<port>[0-9]*)') + else: + p = re.compile (r'(?P<username>)(?P<password>)(?P<hostname>[^:]*):?(?P<port>[0-9]*)') + m = p.search (hcs) + d = m.groupdict() + d['password'] = d['password'].replace('\\@','@') + return d + +def pretty_box (s, rows=24, cols=80): + """This puts an ASCII text box around the given string. + """ + top_bot = '+' + '-'*cols + '+\n' + return top_bot + '\n'.join(['|'+line+'|' for line in s.split('\n')]) + '\n' + top_bot + +def main (): + if os.getenv('REQUEST_METHOD') is None: + server_cli() + else: + client_cgi() + +# It's mostly HTML and Javascript from here on out. +CGISH_HTML="""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> +<title>%(TITLE)s %(SID)s</title> +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> +<style type=text/css> +a {color: #9f9; text-decoration: none} +a:hover {color: #0f0} +hr {color: #0f0} +html,body,textarea,input,form +{ +font-family: "Courier New", Courier, mono; +font-size: 8pt; +color: #0c0; +background-color: #020; +margin:0; +padding:0; +border:0; +} +input { background-color: #010; } +textarea { +border-width:1; +border-style:solid; +border-color:#0c0; +padding:3; +margin:3; +} +</style> + +<script language="JavaScript"> +function focus_first() +{if (document.forms.length > 0) +{var TForm = document.forms[0]; +for (i=0;i<TForm.length;i++){ +if ((TForm.elements[i].type=="text")|| +(TForm.elements[i].type=="textarea")|| +(TForm.elements[i].type.toString().charAt(0)=="s")) +{document.forms[0].elements[i].focus();break;}}}} + +// JavaScript Virtual Keyboard +// If you like this code then buy me a sandwich. +// Noah Spurrier <[email protected]> +var flag_shift=0; +var flag_shiftlock=0; +var flag_ctrl=0; +var ButtonOnColor="#ee0"; + +function init () +{ + // hack to set quote key to show both single quote and double quote + document.form['quote'].value = "'" + ' "'; + //refresh_screen(); + poll(); + document.form["cli"].focus(); +} +function get_password () +{ + var username = prompt("username?",""); + var password = prompt("password?",""); + start_server (username, password); +} +function multibrowser_ajax () +{ + var xmlHttp = false; +/*@cc_on @*/ +/*@if (@_jscript_version >= 5) + try + { + xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); + } + catch (e) + { + try + { + xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); + } + catch (e2) + { + xmlHttp = false; + } + } +@end @*/ + + if (!xmlHttp && typeof XMLHttpRequest != 'undefined') + { + xmlHttp = new XMLHttpRequest(); + } + return xmlHttp; +} +function load_url_to_screen(url) +{ + xmlhttp = multibrowser_ajax(); + //window.XMLHttpRequest?new XMLHttpRequest(): new ActiveXObject("Microsoft.XMLHTTP"); + xmlhttp.onreadystatechange = update_virtual_screen; + xmlhttp.open("GET", url); + xmlhttp.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"); + xmlhttp.send(null); +} +function update_virtual_screen() +{ + if ((xmlhttp.readyState == 4) && (xmlhttp.status == 200)) + { + var screen_text = xmlhttp.responseText; + document.form["screen_text"].value = screen_text; + //var json_data = json_parse(xmlhttp.responseText); + } +} +function poll() +{ + refresh_screen(); + timerID = setTimeout("poll()", 2000); + // clearTimeout(timerID); +} +//function start_server (username, password) +//{ +// load_url_to_screen('cgishell.cgi?ajax=serverstart&username=' + escape(username) + '&password=' + escape(password); +//} +function refresh_screen() +{ + load_url_to_screen('cgishell.cgi?ajax=refresh&sid=%(SID)s'); +} +function query_hash() +{ + load_url_to_screen('cgishell.cgi?ajax=hash&sid=%(SID)s'); +} +function query_cursor() +{ + load_url_to_screen('cgishell.cgi?ajax=cursor&sid=%(SID)s'); +} +function exit_server() +{ + load_url_to_screen('cgishell.cgi?ajax=exit&sid=%(SID)s'); +} +function type_key (chars) +{ + var ch = '?'; + if (flag_shiftlock || flag_shift) + { + ch = chars.substr(1,1); + } + else if (flag_ctrl) + { + ch = chars.substr(2,1); + } + else + { + ch = chars.substr(0,1); + } + load_url_to_screen('cgishell.cgi?ajax=send&sid=%(SID)s&arg=' + escape(ch)); + if (flag_shift || flag_ctrl) + { + flag_shift = 0; + flag_ctrl = 0; + } + update_button_colors(); +} + +function key_shiftlock() +{ + flag_ctrl = 0; + flag_shift = 0; + if (flag_shiftlock) + { + flag_shiftlock = 0; + } + else + { + flag_shiftlock = 1; + } + update_button_colors(); +} + +function key_shift() +{ + if (flag_shift) + { + flag_shift = 0; + } + else + { + flag_ctrl = 0; + flag_shiftlock = 0; + flag_shift = 1; + } + update_button_colors(); +} +function key_ctrl () +{ + if (flag_ctrl) + { + flag_ctrl = 0; + } + else + { + flag_ctrl = 1; + flag_shiftlock = 0; + flag_shift = 0; + } + + update_button_colors(); +} +function update_button_colors () +{ + if (flag_ctrl) + { + document.form['Ctrl'].style.backgroundColor = ButtonOnColor; + document.form['Ctrl2'].style.backgroundColor = ButtonOnColor; + } + else + { + document.form['Ctrl'].style.backgroundColor = document.form.style.backgroundColor; + document.form['Ctrl2'].style.backgroundColor = document.form.style.backgroundColor; + } + if (flag_shift) + { + document.form['Shift'].style.backgroundColor = ButtonOnColor; + document.form['Shift2'].style.backgroundColor = ButtonOnColor; + } + else + { + document.form['Shift'].style.backgroundColor = document.form.style.backgroundColor; + document.form['Shift2'].style.backgroundColor = document.form.style.backgroundColor; + } + if (flag_shiftlock) + { + document.form['ShiftLock'].style.backgroundColor = ButtonOnColor; + } + else + { + document.form['ShiftLock'].style.backgroundColor = document.form.style.backgroundColor; + } + +} +function keyHandler(e) +{ + var pressedKey; + if (document.all) { e = window.event; } + if (document.layers) { pressedKey = e.which; } + if (document.all) { pressedKey = e.keyCode; } + pressedCharacter = String.fromCharCode(pressedKey); + type_key(pressedCharacter+pressedCharacter+pressedCharacter); + alert(pressedCharacter); +// alert(' Character = ' + pressedCharacter + ' [Decimal value = ' + pressedKey + ']'); +} +//document.onkeypress = keyHandler; +//if (document.layers) +// document.captureEvents(Event.KEYPRESS); +//http://sniptools.com/jskeys +//document.onkeyup = KeyCheck; +function KeyCheck(e) +{ + var KeyID = (window.event) ? event.keyCode : e.keyCode; + type_key(String.fromCharCode(KeyID)); + e.cancelBubble = true; + window.event.cancelBubble = true; +} +</script> + +</head> + +<body onload="init()"> +<form id="form" name="form" action="/cgi-bin/cgishell.cgi" method="POST"> +<input name="sid" value="%(SID)s" type="hidden"> +<textarea name="screen_text" cols="81" rows="25">%(SHELL_OUTPUT)s</textarea> +<hr noshade="1"> + <input name="cli" id="cli" type="text" size="80"><br> +<table border="0" align="left"> +<tr> +<td width="86%%" align="center"> + <input name="submit" type="submit" value="Submit"> + <input name="refresh" type="button" value="REFRESH" onclick="refresh_screen()"> + <input name="refresh" type="button" value="CURSOR" onclick="query_cursor()"> + <input name="hash" type="button" value="HASH" onclick="query_hash()"> + <input name="exit" type="button" value="EXIT" onclick="exit_server()"> + <br> + <input type="button" value="Esc" onclick="type_key('\\x1b\\x1b')" /> + <input type="button" value="` ~" onclick="type_key('`~')" /> + <input type="button" value="1!" onclick="type_key('1!')" /> + <input type="button" value="2@" onclick="type_key('2@\\x00')" /> + <input type="button" value="3#" onclick="type_key('3#')" /> + <input type="button" value="4$" onclick="type_key('4$')" /> + <input type="button" value="5%%" onclick="type_key('5%%')" /> + <input type="button" value="6^" onclick="type_key('6^\\x1E')" /> + <input type="button" value="7&" onclick="type_key('7&')" /> + <input type="button" value="8*" onclick="type_key('8*')" /> + <input type="button" value="9(" onclick="type_key('9(')" /> + <input type="button" value="0)" onclick="type_key('0)')" /> + <input type="button" value="-_" onclick="type_key('-_\\x1F')" /> + <input type="button" value="=+" onclick="type_key('=+')" /> + <input type="button" value="BkSp" onclick="type_key('\\x08\\x08\\x08')" /> + <br> + <input type="button" value="Tab" onclick="type_key('\\t\\t')" /> + <input type="button" value="Q" onclick="type_key('qQ\\x11')" /> + <input type="button" value="W" onclick="type_key('wW\\x17')" /> + <input type="button" value="E" onclick="type_key('eE\\x05')" /> + <input type="button" value="R" onclick="type_key('rR\\x12')" /> + <input type="button" value="T" onclick="type_key('tT\\x14')" /> + <input type="button" value="Y" onclick="type_key('yY\\x19')" /> + <input type="button" value="U" onclick="type_key('uU\\x15')" /> + <input type="button" value="I" onclick="type_key('iI\\x09')" /> + <input type="button" value="O" onclick="type_key('oO\\x0F')" /> + <input type="button" value="P" onclick="type_key('pP\\x10')" /> + <input type="button" value="[ {" onclick="type_key('[{\\x1b')" /> + <input type="button" value="] }" onclick="type_key(']}\\x1d')" /> + <input type="button" value="\\ |" onclick="type_key('\\\\|\\x1c')" /> + <br> + <input type="button" id="Ctrl" value="Ctrl" onclick="key_ctrl()" /> + <input type="button" value="A" onclick="type_key('aA\\x01')" /> + <input type="button" value="S" onclick="type_key('sS\\x13')" /> + <input type="button" value="D" onclick="type_key('dD\\x04')" /> + <input type="button" value="F" onclick="type_key('fF\\x06')" /> + <input type="button" value="G" onclick="type_key('gG\\x07')" /> + <input type="button" value="H" onclick="type_key('hH\\x08')" /> + <input type="button" value="J" onclick="type_key('jJ\\x0A')" /> + <input type="button" value="K" onclick="type_key('kK\\x0B')" /> + <input type="button" value="L" onclick="type_key('lL\\x0C')" /> + <input type="button" value="; :" onclick="type_key(';:')" /> + <input type="button" id="quote" value="'" onclick="type_key('\\x27\\x22')" /> + <input type="button" value="Enter" onclick="type_key('\\n\\n')" /> + <br> + <input type="button" id="ShiftLock" value="Caps Lock" onclick="key_shiftlock()" /> + <input type="button" id="Shift" value="Shift" onclick="key_shift()" /> + <input type="button" value="Z" onclick="type_key('zZ\\x1A')" /> + <input type="button" value="X" onclick="type_key('xX\\x18')" /> + <input type="button" value="C" onclick="type_key('cC\\x03')" /> + <input type="button" value="V" onclick="type_key('vV\\x16')" /> + <input type="button" value="B" onclick="type_key('bB\\x02')" /> + <input type="button" value="N" onclick="type_key('nN\\x0E')" /> + <input type="button" value="M" onclick="type_key('mM\\x0D')" /> + <input type="button" value=", <" onclick="type_key(',<')" /> + <input type="button" value=". >" onclick="type_key('.>')" /> + <input type="button" value="/ ?" onclick="type_key('/?')" /> + <input type="button" id="Shift2" value="Shift" onclick="key_shift()" /> + <input type="button" id="Ctrl2" value="Ctrl" onclick="key_ctrl()" /> + <br> + <input type="button" value=" FINAL FRONTIER " onclick="type_key(' ')" /> +</td> +</tr> +</table> +</form> +</body> +</html> +""" + +LOGIN_HTML="""<html> +<head> +<title>Shell Login</title> +<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> +<style type=text/css> +a {color: #9f9; text-decoration: none} +a:hover {color: #0f0} +hr {color: #0f0} +html,body,textarea,input,form +{ +font-family: "Courier New", Courier, mono; +font-size: 8pt; +color: #0c0; +background-color: #020; +margin:3; +padding:0; +border:0; +} +input { background-color: #010; } +input,textarea { +border-width:1; +border-style:solid; +border-color:#0c0; +padding:3; +margin:3; +} +</style> +<script language="JavaScript"> +function init () +{ + document.login_form["username"].focus(); +} +</script> +</head> +<body onload="init()"> +<form name="login_form" method="POST"> +<input name="start_server" value="1" type="hidden"> +<input name="sid" value="%(SID)s" type="hidden"> +username: <input name="username" type="text" size="30"><br> +password: <input name="password" type="password" size="30"><br> +<input name="submit" type="submit" value="enter"> +</form> +<br> +</body> +</html> +""" + +if __name__ == "__main__": + try: + main() + except Exception as e: + print(str(e)) + tb_dump = traceback.format_exc() + print(str(tb_dump)) + http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/chess.py ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/chess.py b/tools/bin/pythonSrc/pexpect-4.2/examples/chess.py new file mode 100755 index 0000000..421727d --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/chess.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python + +'''This demonstrates controlling a screen oriented application (curses). +It starts two instances of gnuchess and then pits them against each other. + +PEXPECT LICENSE + + This license is approved by the OSI and FSF as GPL-compatible. + http://opensource.org/licenses/isc-license.txt + + Copyright (c) 2012, Noah Spurrier <[email protected]> + PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY + PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE + COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +''' + +from __future__ import print_function + +from __future__ import absolute_import + +import pexpect +import ANSI + +REGEX_MOVE = '(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)' +REGEX_MOVE_PART = '(?:[0-9]|\x1b\[C)(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)' + +class Chess: + + def __init__(self, engine = "/usr/local/bin/gnuchess -a -h 1"): + self.child = pexpect.spawn (engine) + self.term = ANSI.ANSI () + + self.child.expect ('Chess') + if self.child.after != 'Chess': + raise IOError('incompatible chess program') + self.term.process_list (self.before) + self.term.process_list (self.after) + self.last_computer_move = '' + + def read_until_cursor (self, r,c): + while 1: + self.child.read(1, 60) + self.term.process (c) + if self.term.cur_r == r and self.term.cur_c == c: + return 1 + + def do_first_move (self, move): + self.child.expect ('Your move is') + self.child.sendline (move) + self.term.process_list (self.before) + self.term.process_list (self.after) + return move + + def do_move (self, move): + self.read_until_cursor (19,60) + self.child.sendline (move) + return move + + def get_first_computer_move (self): + self.child.expect ('My move is') + self.child.expect (REGEX_MOVE) + return self.child.after + + def get_computer_move (self): + print('Here') + i = self.child.expect (['\[17;59H', '\[17;58H']) + print(i) + if i == 0: + self.child.expect (REGEX_MOVE) + if len(self.child.after) < 4: + self.child.after = self.child.after + self.last_computer_move[3] + if i == 1: + self.child.expect (REGEX_MOVE_PART) + self.child.after = self.last_computer_move[0] + self.child.after + print('', self.child.after) + self.last_computer_move = self.child.after + return self.child.after + + def switch (self): + self.child.sendline ('switch') + + def set_depth (self, depth): + self.child.sendline ('depth') + self.child.expect ('depth=') + self.child.sendline ('%d' % depth) + + def quit(self): + self.child.sendline ('quit') +import sys +print('Starting...') +white = Chess() +white.child.echo = 1 +white.child.expect ('Your move is') +white.set_depth(2) +white.switch() + +move_white = white.get_first_computer_move() +print('first move white:', move_white) + +white.do_move ('e7e5') +move_white = white.get_computer_move() +print('move white:', move_white) +white.do_move ('f8c5') +move_white = white.get_computer_move() +print('move white:', move_white) +white.do_move ('b8a6') +move_white = white.get_computer_move() +print('move white:', move_white) + +sys.exit(1) + + + +black = Chess() +white = Chess() +white.child.expect ('Your move is') +white.switch() + +move_white = white.get_first_computer_move() +print('first move white:', move_white) + +black.do_first_move (move_white) +move_black = black.get_first_computer_move() +print('first move black:', move_black) + +white.do_move (move_black) + +done = 0 +while not done: + move_white = white.get_computer_move() + print('move white:', move_white) + + black.do_move (move_white) + move_black = black.get_computer_move() + print('move black:', move_black) + + white.do_move (move_black) + print('tail of loop') + +g.quit() http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/chess2.py ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/chess2.py b/tools/bin/pythonSrc/pexpect-4.2/examples/chess2.py new file mode 100755 index 0000000..b92509e --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/chess2.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python + +'''This demonstrates controlling a screen oriented application (curses). +It starts two instances of gnuchess and then pits them against each other. + +PEXPECT LICENSE + + This license is approved by the OSI and FSF as GPL-compatible. + http://opensource.org/licenses/isc-license.txt + + Copyright (c) 2012, Noah Spurrier <[email protected]> + PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY + PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE + COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +''' + +from __future__ import print_function + +from __future__ import absolute_import + +import pexpect +import ANSI +import sys +import time + +class Chess: + + def __init__(self, engine = "/usr/local/bin/gnuchess -a -h 1"): + self.child = pexpect.spawn (engine) + self.term = ANSI.ANSI () + + #self.child.expect ('Chess') + #if self.child.after != 'Chess': + # raise IOError, 'incompatible chess program' + #self.term.process_list (self.child.before) + #self.term.process_list (self.child.after) + + self.last_computer_move = '' + + def read_until_cursor (self, r,c, e=0): + '''Eventually something like this should move into the screen class or + a subclass. Maybe a combination of pexpect and screen... + ''' + fout = open ('log','a') + while self.term.cur_r != r or self.term.cur_c != c: + try: + k = self.child.read(1, 10) + except Exception as e: + print('EXCEPTION, (r,c):(%d,%d)\n' %(self.term.cur_r, self.term.cur_c)) + sys.stdout.flush() + self.term.process (k) + fout.write ('(r,c):(%d,%d)\n' %(self.term.cur_r, self.term.cur_c)) + fout.flush() + if e: + sys.stdout.write (k) + sys.stdout.flush() + if self.term.cur_r == r and self.term.cur_c == c: + fout.close() + return 1 + print('DIDNT EVEN HIT.') + fout.close() + return 1 + + def expect_region (self): + '''This is another method that would be moved into the + screen class. + ''' + pass + def do_scan (self): + fout = open ('log','a') + while 1: + c = self.child.read(1,10) + self.term.process (c) + fout.write ('(r,c):(%d,%d)\n' %(self.term.cur_r, self.term.cur_c)) + fout.flush() + sys.stdout.write (c) + sys.stdout.flush() + + def do_move (self, move, e = 0): + time.sleep(1) + self.read_until_cursor (19,60, e) + self.child.sendline (move) + + def wait (self, color): + while 1: + r = self.term.get_region (14,50,14,60)[0] + r = r.strip() + if r == color: + return + time.sleep (1) + + def parse_computer_move (self, s): + i = s.find ('is: ') + cm = s[i+3:i+9] + return cm + def get_computer_move (self, e = 0): + time.sleep(1) + self.read_until_cursor (19,60, e) + time.sleep(1) + r = self.term.get_region (17,50,17,62)[0] + cm = self.parse_computer_move (r) + return cm + + def switch (self): + print('switching') + self.child.sendline ('switch') + + def set_depth (self, depth): + self.child.sendline ('depth') + self.child.expect ('depth=') + self.child.sendline ('%d' % depth) + + def quit(self): + self.child.sendline ('quit') + +def LOG (s): + print(s) + sys.stdout.flush () + fout = open ('moves.log', 'a') + fout.write (s + '\n') + fout.close() + +print('Starting...') + +black = Chess() +white = Chess() +white.read_until_cursor (19,60,1) +white.switch() + +done = 0 +while not done: + white.wait ('Black') + move_white = white.get_computer_move(1) + LOG ( 'move white:'+ move_white ) + + black.do_move (move_white) + black.wait ('White') + move_black = black.get_computer_move() + LOG ( 'move black:'+ move_black ) + + white.do_move (move_black, 1) + +g.quit() + +
