--- /dev/null
+#!/usr/bin/python
+#
+# curses_check_for_keypress - loop until user presses a key.
+#
+# Copyright (C) 2008-2009 William Trevor King
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# The author may be contacted at <wking@drexel.edu> on the Internet, or
+# write to Trevor King, Drexel University, Physics Dept., 3141 Chestnut St.,
+# Philadelphia PA 19104, USA.
+
+
+import curses, curses.ascii
+import time
+import sys
+import StringIO
+# http://www.amk.ca/python/howto/curses/curses.html
+
+VERSION = "0.1"
+
+def quiet_sleep() :
+ time.sleep(.1)
+
+def test_sleep() :
+ time.sleep(.5)
+
+class check_for_keypress :
+ def __init__(self, prompt="Press any key to continue",
+ timeout_ms=0, test_mode=False) :
+ self.test_mode = test_mode
+ self.last = None # last byte number read
+ self.lasta = None # last as an ASCII character
+ if test_mode == True :
+ print prompt
+ self.i = 0
+ return None
+ # redirect stderr to a file, because exiting curses mode clears
+ # any error messages that had been printed to the screen
+ sys.stderr = StringIO.StringIO()
+ # initialize raw curses mode
+ self.stdscr = curses.initscr()
+ curses.noecho()
+ curses.cbreak()
+ self.stdscr.scrollok(1)
+ try :
+ self.stdscr.addstr(0,0,prompt+"\n")
+ if timeout_ms <= 0 :
+ self.stdscr.nodelay(True)
+ else :
+ self.stdscr.halfdelay(timeout_ms)
+ except :
+ self.close()
+ def __del__(self) :
+ self.close()
+ def close(self) :
+ if self.test_mode == True :
+ return None
+ # return to standard terminal
+ while self.input() != None : # eat up the buffer
+ pass
+ self.stdscr.scrollok(0)
+ curses.nocbreak()
+ curses.echo()
+ curses.endwin()
+ # print any errors and restore stderr
+ contents = sys.stderr.getvalue()
+ sys.stderr = sys.__stderr__
+ if len(contents) > 0 :
+ print contents
+ def input(self) :
+ if self.test_mode == True :
+ if self.i < 10 :
+ self.i += 1
+ return None
+ else :
+ return "a"
+ c = self.stdscr.getch()
+ if c == curses.ERR :
+ return None
+ else :
+ self.last = c
+ self.lasta = curses.ascii.unctrl(c)
+ return c
+ def inputa(self) :
+ c = self.input()
+ if c == None :
+ return None
+ else :
+ return self.lasta
+ def _output(self, string) :
+ if self.test_mode == True :
+ print string,
+ return None
+ #y,x = self.stdscr.getyx()
+ self.stdscr.addstr(string)
+ def _flush(self) :
+ if self.test_mode == True :
+ return None
+ self.stdscr.refresh()
+ def output(self, string) :
+ self._output(string)
+ self._flush()
+
+def _test_usual_usage() :
+ c=check_for_keypress('testing usual usage, press any key to stop loop...')
+ i = 0
+ while c.input() == None :
+ test_sleep()
+ c.output('sleeping\n')
+ if i > 1000:
+ raise Exception, "you didn't press a key!"
+ i += 1
+ del(c)
+
+def _test_error_catching() :
+ c=check_for_keypress('testing error catching, wait for the error...')
+ i = 0
+ class _testException (Exception):
+ pass
+ try:
+ while c.input() == None :
+ if i > 4 :
+ print >> sys.stderr, "testing error output"
+ raise _testException, "testing error exception"
+ test_sleep()
+ c.output('sleeping\n')
+ i += 1
+ raise Exception, "_test_error_catching() failed!"
+ except _testException, e:
+ assert len(sys.stderr.getvalue()) > 0, "No error message!"
+ del(c)
+
+def test() :
+ _test_usual_usage()
+ _test_error_catching()
+
+if __name__ == "__main__" :
+ test()
--- /dev/null
+"""curses_check_for_keypress: loop until user presses a key.
+"""
+
+classifiers = """\
+Development Status :: 2 - Pre-Alpha
+Intended Audience :: Developers
+Operating System :: OS Independent
+License :: OSI Approved :: GNU General Public License (GPL)
+Programming Language :: Python
+Topic :: Software Development :: Libraries :: Python Modules
+"""
+
+# http://peak.telecommunity.com/DevCenter/setuptools#using-setuptools-without-bundling-it
+import ez_setup
+ez_setup.use_setuptools()
+
+from setuptools import setup, find_packages
+
+# patch distutils if it can't cope with the "classifiers" or
+# "download_url" keywords
+from sys import version
+if version < '2.2.3':
+ from distutils.dist import DistributionMetadata
+ DistributionMetadata.classifiers = None
+ DistributionMetadata.download_url = None
+
+doclines = __doc__.split("\n")
+
+from curses_check_for_keypress import VERSION
+
+setup(name="curses_check_for_keypress",
+ version=VERSION,
+ maintainer="W. Trevor King",
+ maintainer_email="wking@drexel.edu",
+ url = "http://www.physics.drexel.edu/~wking/code/python/",
+ download_url = "http://www.physics.drexel.edu/~wking/code/python/curses_check_for_keypress-%s.tar.gz" % VERSION,
+ license = "GNU General Public License (GPL)",
+ platforms = ["all"],
+ description = doclines[0],
+ long_description = "\n".join(doclines[2:]),
+ classifiers = filter(None, classifiers.split("\n")),
+ py_modules = ["curses_check_for_keypress", "ez_setup"],
+ #packages = find_packages(),
+ )
+
+# use packages to include subdirectory packages
+# use py_modules to include single-module packages
+# use ext_modules to include extension modules
+# see
+# http://www.python.org/doc/2.5.2/dist/listing-modules.html
+# http://www.python.org/doc/2.5.2/dist/describing-extensions.html