summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rwxr-xr-xnoncore/tools/pyquicklauncher/quicklauncher.py182
-rwxr-xr-xnoncore/tools/pyquicklauncher/testapp.py24
2 files changed, 206 insertions, 0 deletions
diff --git a/noncore/tools/pyquicklauncher/quicklauncher.py b/noncore/tools/pyquicklauncher/quicklauncher.py
new file mode 100755
index 0000000..9a4985f
--- a/dev/null
+++ b/noncore/tools/pyquicklauncher/quicklauncher.py
@@ -0,0 +1,182 @@
1#!/usr/bin/env python
2# -*- coding: iso8859-15 -*-
3#--------------------------------------------------------------------------------------------------#
4""" M i c k e y ' s
5 P y t h o n
6 Q u i c k l a u n c h e r
7
8 =. Copyright (C) 2004 Michael Lauer
9 .=l. <mickey@tm.informatik.uni-frankfurt.de>
10           .>+-=
11 _;:,     .>    :=|. This program is free software; you can
12.> <`_,   >  .   <= redistribute it and/or modify it under
13:`=1 )Y*s>-.--   : the terms of the GNU General Public
14.="- .-=="i,     .._ License as published by the Free Software
15 - .   .-<_>     .<> Foundation; either version 2 of the License,
16     ._= =}       : or (at your option) any later version.
17    .%`+i>       _;_.
18    .i_,=:_.      -<s. This program is distributed in the hope that
19     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
20    : ..    .:,     . . . without even the implied warranty of
21    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
22  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
23..}^=.=       =       ; General Public License for more
24++=   -.     .`     .: details.
25 :     =  ...= . :.=-
26 -.   .:....=;==+<; You should have received a copy of the
27  -_. . .   )=.  = GNU General Public License along with
28    --        :-=` this library; see the file COPYING.LIB.
29 If not, write to the Free Software Foundation,
30 Inc., 59 Temple Place - Suite 330,
31 Boston, MA 02111-1307, USA.
32
33 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
34
35Purpose: This module is
36
37At the moment, it is optimized for PyQt. Feel free to port it to PyGtk or other modules.
38
39"""
40
41#--------------------------------------------------------------------------------------------------#
42__version__ = "0.0.1"
43__author__ = "Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de>"
44__license__ = "GPL"
45#--------------------------------------------------------------------------------------------------#
46try:
47 from qtpe import QPEApplication as ApplicationBase
48except ImportError:
49 from qt import QApplication as ApplicationBase
50
51import sys, os
52
53# <MODULE PRELOAD SECTION>
54# Note: Feel free to add other modules to accellerate the startup of your Application.
55from qt import *
56import qt
57# </MODULE PRELOAD SECTION>
58
59#
60# FIXME: use the ELAN common debug framework
61#
62def TRACE( *args ):
63 for arg in args:
64 sys.stderr.write( "%s - " % arg )
65 sys.stderr.write( "\n" )
66TERROR = TDEBUG = TINFO = TWARN = TRACE
67
68#--------------------------------------------------------------------------------------------------#
69class QuicklauncherServer( ApplicationBase ):
70 """The Quicklauncher Server loads other Python Applications as plugins.
71
72 The Quicklauncher server is the one and only Python process in the system.
73 It also is the creator of the one and only Qt application object, no matter
74 if it is a QPEApplication or a QApplication.
75
76 Quicklauncher server and clients communicate via a FIFO (named pipe), this enables
77 us to write clients as easy as the following example:
78
79 #!/bin/sh
80 echo /path/to/your/python/script.py >/tmp/mickeys-quicklauncher-$USER
81 """
82
83
84 def __init__( self, name = "/tmp/mickeys-quicklauncher-%s" % os.getenv( "USER") ):
85 """Initialize the Quicklauncher & setup the FIFO."""
86 ApplicationBase.__init__( self, sys.argv[1:] )
87 try:
88 os.mkfifo( name )
89 except OSError, reason:
90 pass
91 self.socketNotifier = None
92 self.fileno = 0
93 self.name = name
94 self.reopenFifo()
95 self.sendToApplet( "setOnline()" )
96 self.sendToApplet( "test(QString,int)", "Hallo", 20 )
97
98 def __del__( self ):
99 """Delete the FIFO if present."""
100 os.unlink( self.name )
101 self.sendCommand( "setOffline()" )
102
103 def sendToApplet( self, command, *params ):
104 TDEBUG( self, "sending to applet: '%s' '%s'" % ( command, params ) )
105 cmdline = 'qcop "QPE/PyLauncher" "%s"' % command
106 for param in params:
107 cmdline += ' "%s"' % param
108 TDEBUG( self, "calling '%s'" % cmdline )
109 os.system( cmdline )
110
111 def reopenFifo( self ):
112 """Close and reopen the FIFO. Setup a QSocketNotifier to get the
113 Qt event loop notifying us when someone is requesting an application start."""
114 del self.socketNotifier
115 os.close( self.fileno )
116 self.fileno = os.open( self.name, os.O_RDONLY|os.O_NONBLOCK )
117 TDEBUG( self, "created communication fifo '%s'" % self.name )
118 self.socketNotifier = qt.QSocketNotifier( self.fileno, qt.QSocketNotifier.Read )
119 qt.QObject.connect( self.socketNotifier, qt.SIGNAL( "activated(int)" ), self.slotHandleMessage )
120
121 def run( self ):
122 """Register socket notifier and start main loop"""
123 TDEBUG( self, "---> entering main loop." )
124 try:
125 self.exec_loop()
126 except Exception, reason:
127 TERROR( self, "Exception during main loop: '%s'" % reason )
128 self.quit()
129 TDEBUG( self, "<--- returned from main loop." )
130
131 def slotHandleMessage( self, fileno ):
132 """Called by the main loop when there is incoming data at the FIFO."""
133 TDEBUG( self, "handle message called." )
134 scriptName = os.read( self.fileno, 1000 ).strip()
135 garbage = os.read( self.fileno, -1 )
136 if scriptName.startswith( "quit" ):
137 self.quit()
138 TDEBUG( self, "Module to launch = '%s'" % ( scriptName ) )
139 self.reopenFifo()
140 #
141 # Remove QApplication from the namespace and inject our substitute
142 #
143 global QApplication
144 QApplication = QuickApplication
145 qt.QApplication = QuickApplication
146
147 modulename = self.importModule( scriptName )
148 module = sys.modules[modulename]
149
150 def importModule( self, name ):
151 """Import a module by pathname and return the module name."""
152 dirname, modulename = os.path.dirname( name ), os.path.basename( name )
153 sys.path.append( dirname )
154 try:
155 if modulename[-3:] == ".py":
156 modulename = modulename[:-3]
157 module = __import__( modulename )
158 except ImportError, reason:
159 TERROR( self, "Can't import '%s' (%s)" % ( modulename, reason ) )
160 else:
161 TDEBUG( self, "Module '%s' been imported = %s" % ( modulename, module ) )
162 return modulename
163
164#--------------------------------------------------------------------------------------------------#
165class QuickApplication( object ):
166 """This class acts as proxy for the real Q[PE]Application class.
167 This way we keep the system state sane by only allowing one application object,
168 which is the one the server already created for us."""
169
170 def __getattribute__( self, attr ):
171 """Mimick a simply attribute resolution order:
172 First, look in the application object (the server in this case).
173 Second, hand lookup over to the built-in object base class."""
174 #print "__getattribute__", attr
175 return getattr( server, attr, None ) or object.__getattribute__( self, attr )
176
177#--------------------------------------------------------------------------------------------------#
178
179if __name__ == "__main__":
180 print >>sys.stdout, "Mickey's Quicklauncher Version %s booting..." % ( __version__ )
181 server = QuicklauncherServer()
182 server.run()
diff --git a/noncore/tools/pyquicklauncher/testapp.py b/noncore/tools/pyquicklauncher/testapp.py
new file mode 100755
index 0000000..8345193
--- a/dev/null
+++ b/noncore/tools/pyquicklauncher/testapp.py
@@ -0,0 +1,24 @@
1#!/usr/bin/env python
2# -*- coding: iso8859-15 -*-
3#--------------------------------------------------------------------------------------------------#
4from qt import *
5import sys
6#--------------------------------------------------------------------------------------------------#
7class MyApplication( QApplication ):
8
9 def __init__( self, argv ):
10 QApplication.__init__( self, [] )
11 self.b = QPushButton( """This is an example application using Mickey's
12fascinating Python Quicklaunch technology!
13Close me to quit this application.""", None )
14 self.b.show()
15 self.setMainWidget( self.b )
16#--------------------------------------------------------------------------------------------------#
17
18if __name__ == "__main__":
19 print "Standalone!"
20else:
21 print "Quickapp!"
22
23 app = MyApplication( sys.argv )
24 app.exec_loop()