- Timestamp:
- 10/06/08 00:29:29 (16 years ago)
- Location:
- pykoticon/trunk
- Files:
-
- 9 modified
Legend:
- Unmodified
- Added
- Removed
-
pykoticon/trunk/bin/pykoticon
r180 r3439 1 1 #! /usr/bin/env python 2 # -*- coding: ISO-8859-15 -*-2 # -*- coding: iso-8859-15 -*- 3 3 4 4 """PyKotIcon is a generic, networked, cross-platform dialog box manager.""" … … 16 16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 17 # GNU General Public License for more details. 18 # 18 # 19 19 # You should have received a copy of the GNU General Public License 20 20 # along with this program; if not, write to the Free Software … … 45 45 try : 46 46 import optparse 47 except ImportError : 47 except ImportError : 48 48 sys.stderr.write("You need Python v2.3 or higher for PyKotIcon to work.\nAborted.\n") 49 49 sys.exit(-1) … … 53 53 try : 54 54 import win32api 55 except ImportError : 55 except ImportError : 56 56 raise ImportError, "Mark Hammond's Win32 Extensions are missing. Please install them." 57 else : 57 else : 58 58 iconsdir = os.path.split(sys.argv[0])[0] 59 else : 59 else : 60 60 isWindows = False 61 61 iconsdir = "/usr/share/pykoticon" # TODO : change this 62 62 import pwd 63 64 try : 63 64 try : 65 65 import wx 66 66 hasWxPython = True 67 except ImportError : 67 except ImportError : 68 68 hasWxPython = False 69 69 raise ImportError, "wxPython is missing. Please install it." 70 70 71 71 aboutbox = """PyKotIcon v%(__version__)s (c) 2003-2006 %(__author__)s - %(__author_email__)s 72 72 … … 98 98 try : 99 99 SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self) 100 except TypeError : 100 except TypeError : 101 101 SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self, False, None) 102 102 SocketServer.ThreadingTCPServer.__init__(self, addr, requestHandler) 103 103 104 104 class MyXMLRPCServer(ThreadedXMLRPCServer) : 105 105 """My own server class.""" … … 119 119 loop = threading.Thread(target=self.mainloop) 120 120 loop.start() 121 122 def logDebug(self, message) : 121 122 def logDebug(self, message) : 123 123 """Logs a debug message if debug mode is active.""" 124 124 if self.debug : 125 125 sys.stderr.write("%s\n" % message) 126 126 127 127 def getAnswerFromCache(self, key) : 128 128 """Tries to extract a value from the cache and returns it if still valid.""" 129 129 cacheentry = self.cache.get(key) 130 130 if cacheentry is not None : 131 (birth, value) = cacheentry 131 (birth, value) = cacheentry 132 132 if (time.time() - birth) < self.cacheduration : 133 133 self.logDebug("Cache hit for %s" % str(key)) 134 134 return value # NB : we don't extend the life of this entry 135 else : 135 else : 136 136 self.logDebug("Cache expired for %s" % str(key)) 137 else : 137 else : 138 138 self.logDebug("Cache miss for %s" % str(key)) 139 139 return None 140 141 def storeAnswerInCache(self, key, value) : 140 141 def storeAnswerInCache(self, key, value) : 142 142 """Stores an entry in the cache.""" 143 143 self.cache[key] = (time.time(), value) 144 144 self.logDebug("Cache store for %s" % str(key)) 145 145 146 146 def export_askDatas(self, labels, varnames, varvalues) : 147 147 """Asks some textual datas defined by a list of labels, a list of variables' names and a list of variables values in a mapping.""" … … 149 149 for (key, value) in varvalues.items() : 150 150 values[key] = self.frame.UTF8ToUserCharset(value.data) 151 cachekey = tuple(values.items()) 151 cachekey = tuple(values.items()) 152 152 retcode = self.getAnswerFromCache(cachekey) 153 153 if (retcode is None) or (not retcode["isValid"]) : … … 158 158 while self.frame.dialogAnswer is None : 159 159 time.sleep(0.1) 160 retcode = self.frame.dialogAnswer 160 retcode = self.frame.dialogAnswer 161 161 for (key, value) in retcode.items() : 162 162 if key != "isValid" : … … 165 165 self.storeAnswerInCache(cachekey, retcode) 166 166 return retcode 167 168 def export_quitApplication(self) : 167 168 def export_quitApplication(self) : 169 169 """Makes the application quit.""" 170 170 self.frame.quitEvent.set() 171 171 wx.CallAfter(self.frame.OnClose, None) 172 172 return True 173 173 174 174 def export_showDialog(self, message, yesno) : 175 175 """Opens a notification or confirmation dialog.""" … … 178 178 while self.frame.dialogAnswer is None : 179 179 time.sleep(0.1) 180 retcode = self.frame.dialogAnswer 180 retcode = self.frame.dialogAnswer 181 181 self.frame.dialogAnswer = None # prepare for next call, just in case 182 182 return retcode 183 184 def export_nop(self) : 183 184 def export_nop(self) : 185 185 """Does nothing, but allows a clean shutdown from the frame itself.""" 186 186 return True 187 188 def _dispatch(self, method, params) : 187 188 def _dispatch(self, method, params) : 189 189 """Ensure that only export_* methods are available.""" 190 190 return getattr(self, "export_%s" % method)(*params) 191 192 def handle_error(self, request, client_address) : 191 192 def handle_error(self, request, client_address) : 193 193 """Doesn't display an ugly traceback in case an error occurs.""" 194 194 self.logDebug("An exception occured while handling an incoming request from %s:%s" % (client_address[0], client_address[1])) 195 195 196 196 def verify_request(self, request, client_address) : 197 197 """Ensures that requests which don't come from the print server are rejected.""" … … 204 204 self.logDebug("%s rejected." % client) 205 205 return False 206 206 207 207 def mainloop(self) : 208 208 """XML-RPC Server's main loop.""" … … 213 213 while not self.frame.quitEvent.isSet() : 214 214 self.handle_request() 215 self.server_close() 215 self.server_close() 216 216 sys.exit(0) 217 218 217 218 219 219 class GenericInputDialog(wx.Dialog) : 220 220 """Generic input dialog box.""" … … 233 233 try : 234 234 label = labels[i] 235 except IndexError : 235 except IndexError : 236 236 label = "" 237 labelid = wx.NewId() 237 labelid = wx.NewId() 238 238 varid = wx.NewId() 239 239 labelst = wx.StaticText(self, labelid, label) … … 242 242 else : 243 243 variable = wx.TextCtrl(self, varid, varvalues.get(varname, "")) 244 self.variables.append(variable) 244 self.variables.append(variable) 245 245 hsizer = wx.BoxSizer(wx.HORIZONTAL) 246 246 hsizer.Add(labelst, 0, wx.ALIGN_CENTER | wx.ALIGN_RIGHT | wx.ALL, 5) 247 247 hsizer.Add(variable, 0, wx.ALIGN_CENTER | wx.ALIGN_LEFT | wx.ALL, 5) 248 248 vsizer.Add(hsizer, 0, wx.ALIGN_CENTER | wx.ALL, 5) 249 250 okbutton = wx.Button(self, wx.ID_OK, "OK") 249 250 okbutton = wx.Button(self, wx.ID_OK, "OK") 251 251 vsizer.Add(okbutton, 0, wx.ALIGN_CENTER | wx.ALL, 5) 252 252 if self.variables : … … 255 255 self.SetSizerAndFit(vsizer) 256 256 self.Layout() 257 258 257 258 259 259 class PyKotIcon(wx.Frame): 260 260 """Main class.""" … … 265 265 size = (0, 0), \ 266 266 style = wx.FRAME_NO_TASKBAR | wx.NO_FULL_REPAINT_ON_RESIZE) 267 267 268 268 def getCurrentUserName(self) : 269 269 """Retrieves the current user's name.""" … … 271 271 if isWindows : 272 272 return win32api.GetUserName() 273 else : 273 else : 274 274 return pwd.getpwuid(os.geteuid())[0] 275 275 except : 276 276 return "** Unknown **" 277 277 278 278 def OnIconify(self, event) : 279 279 """Iconify/De-iconify the application.""" … … 299 299 self.Destroy() 300 300 return True 301 else : 301 else : 302 302 # self.quitIsForbidden() 303 303 return False … … 310 310 """React to close from the taskbar.""" 311 311 self.Close() 312 313 def quitIsForbidden(self) : 312 313 def quitIsForbidden(self) : 314 314 """Displays a message indicating that quitting the application is not allowed.""" 315 315 message = _("Sorry, this was forbidden by your system administrator.") … … 319 319 dialog.ShowModal() 320 320 dialog.Destroy() 321 322 def OnAbout(self, event) : 321 322 def OnAbout(self, event) : 323 323 """Displays the about box.""" 324 324 dialog = wx.MessageDialog(self, aboutbox % globals(), \ 325 325 _("About"), \ 326 326 wx.OK | wx.ICON_INFORMATION) 327 dialog.Raise() 327 dialog.Raise() 328 328 dialog.ShowModal() 329 329 dialog.Destroy() 330 330 331 331 def showDialog(self, message, yesno) : 332 332 """Opens a notification dialog.""" … … 338 338 caption = _("Information") 339 339 style = wx.OK | wx.ICON_INFORMATION 340 style |= wx.STAY_ON_TOP 340 style |= wx.STAY_ON_TOP 341 341 dialog = wx.MessageDialog(self, message, caption, style) 342 342 dialog.Raise() 343 343 self.dialogAnswer = ((dialog.ShowModal() == wx.ID_NO) and "CANCEL") or "OK" 344 344 dialog.Destroy() 345 345 346 346 def askDatas(self, labels, varnames, varvalues) : 347 347 """Opens a dialog box asking for data entry.""" … … 354 354 for i in range(len(varnames)) : 355 355 retvalues[varnames[i]] = dialog.variables[i].GetValue() 356 else : 356 else : 357 357 retvalues["isValid"] = False 358 358 for k in varvalues.keys() : … … 360 360 self.dialogAnswer = retvalues 361 361 dialog.Destroy() 362 363 def closeServer(self) : 362 363 def closeServer(self) : 364 364 """Tells the xml-rpc server to exit.""" 365 365 if not self.quitEvent.isSet() : 366 366 self.quitEvent.set() 367 server = xmlrpclib.ServerProxy("http://localhost:%s" % self.options.port) 367 server = xmlrpclib.ServerProxy("http://localhost:%s" % self.options.port) 368 368 try : 369 # wake the server with an empty request 369 # wake the server with an empty request 370 370 # for it to see the event object 371 371 # which has just been set 372 372 server.nop() 373 except : 373 except : 374 374 # Probably already stopped 375 375 pass 376 377 def postInit(self, charset, options, arguments) : 376 377 def postInit(self, charset, options, arguments) : 378 378 """Starts the XML-RPC server.""" 379 379 self.charset = charset 380 380 self.options = options 381 381 382 382 self.tbicon = wx.TaskBarIcon() 383 383 self.greenicon = wx.Icon(os.path.join(iconsdir, "pykoticon-green.ico"), \ … … 386 386 wx.BITMAP_TYPE_ICO) 387 387 self.tbicon.SetIcon(self.greenicon, "PyKotIcon") 388 388 389 389 wx.EVT_TASKBAR_LEFT_DCLICK(self.tbicon, self.OnTaskBarActivate) 390 390 wx.EVT_TASKBAR_RIGHT_UP(self.tbicon, self.OnTaskBarMenu) 391 391 392 392 self.TBMENU_ABOUT = wx.NewId() 393 393 self.TBMENU_RESTORE = wx.NewId() … … 408 408 self.Show(True) 409 409 self.Hide() 410 410 411 411 self.quitEvent = threading.Event() 412 412 self.server = MyXMLRPCServer(self, options, arguments) 413 413 414 414 def UTF8ToUserCharset(self, text) : 415 415 """Converts from UTF-8 to user's charset.""" 416 416 if text is not None : 417 417 try : 418 return text.decode("UTF-8").encode(self.charset, "replace") 419 except (UnicodeError, AttributeError) : 418 return text.decode("UTF-8").encode(self.charset, "replace") 419 except (UnicodeError, AttributeError) : 420 420 try : 421 421 # Maybe already in Unicode 422 return text.encode(self.charset, "replace") 422 return text.encode(self.charset, "replace") 423 423 except (UnicodeError, AttributeError) : 424 424 pass # Don't know what to do 425 425 return text 426 426 427 427 def userCharsetToUTF8(self, text) : 428 428 """Converts from user's charset to UTF-8.""" … … 432 432 except (UnicodeError, AttributeError) : 433 433 try : 434 return text.decode(self.charset, "replace").encode("UTF-8") 435 except (UnicodeError, AttributeError) : 434 return text.decode(self.charset, "replace").encode("UTF-8") 435 except (UnicodeError, AttributeError) : 436 436 try : 437 437 # Maybe already in Unicode 438 return text.encode("UTF-8", "replace") 438 return text.encode("UTF-8", "replace") 439 439 except (UnicodeError, AttributeError) : 440 440 pass # Don't know what to do 441 441 return text 442 442 443 443 444 444 class PyKotIconApp(wx.App): … … 448 448 self.SetTopWindow(self.frame) 449 449 return True 450 451 def postInit(self, charset, options, arguments) : 450 451 def postInit(self, charset, options, arguments) : 452 452 """Continues processing.""" 453 453 self.frame.postInit(charset, options, arguments) 454 455 454 455 456 456 def main() : 457 457 """Program's entry point.""" … … 464 464 language = language or "C" 465 465 charset = ((sys.platform != "win32") and charset) or locale.getpreferredencoding() 466 466 467 467 # translation stuff 468 468 try : … … 474 474 except : 475 475 gettext.NullTranslations().install() 476 477 476 477 478 478 parser = optparse.OptionParser(usage="pykoticon [options] server1 [server2 ...]") 479 parser.add_option("-v", "--version", 480 action="store_true", 479 parser.add_option("-v", "--version", 480 action="store_true", 481 481 dest="version", 482 482 help=_("show PyKotIcon's version number and exit.")) 483 parser.add_option("-c", "--cache", 484 type="int", 485 default=0, 483 parser.add_option("-c", "--cache", 484 type="int", 485 default=0, 486 486 dest="cache", 487 487 help=_("the duration of the cache in seconds to keep input forms' datas in memory. Defaults to 0 second, meaning no cache.")) 488 parser.add_option("-d", "--debug", 489 action="store_true", 488 parser.add_option("-d", "--debug", 489 action="store_true", 490 490 dest="debug", 491 491 help=_("activate debug mode.")) 492 parser.add_option("-p", "--port", 493 type="int", 494 default=7654, 492 parser.add_option("-p", "--port", 493 type="int", 494 default=7654, 495 495 dest="port", 496 496 help=_("the TCP port PyKotIcon will listen to, default is 7654.")) 497 parser.add_option("-q", "--allowquit", 498 action="store_true", 497 parser.add_option("-q", "--allowquit", 498 action="store_true", 499 499 dest="allowquit", 500 500 help=_("allow the end user to close the application.")) … … 505 505 if not (1024 <= options.port <= 65535) : 506 506 sys.stderr.write(_("The TCP port number specified for --port must be between 1024 and 65535.\n")) 507 elif not (0 <= options.cache <= 86400) : 507 elif not (0 <= options.cache <= 86400) : 508 508 sys.stderr.write(_("The duration specified for --cache must be between 0 and 86400 seconds.\n")) 509 else : 509 else : 510 510 app = PyKotIconApp() 511 511 app.postInit(charset, options, arguments) 512 512 app.MainLoop() 513 514 513 514 515 515 if __name__ == '__main__': 516 516 main() 517 517 -
pykoticon/trunk/clean.sh
r141 r3439 13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 # GNU General Public License for more details. 15 # 15 # 16 16 # You should have received a copy of the GNU General Public License 17 17 # along with this program; if not, write to the Free Software -
pykoticon/trunk/CREDITS
r180 r3439 22 22 - Georger Araujo : Fixed a charset encoding problem under MS-Windows. 23 23 - Rodolfo Cossalter : Fixed a problem under MS-Windows 98/Me. 24 24 -
pykoticon/trunk/man/genman.sh
r176 r3439 14 14 # $Id$ 15 15 # 16 for prog in pykoticon ; do 16 for prog in pykoticon ; do 17 17 echo $prog ; 18 help2man --no-info --section=1 --manual "User Commands" --source="C@LL - Conseil Internet & Logiciels Libres" --output=$prog.1 $prog ; 18 help2man --no-info --section=1 --manual "User Commands" --source="C@LL - Conseil Internet & Logiciels Libres" --output=$prog.1 $prog ; 19 19 echo ; 20 20 done -
pykoticon/trunk/NEWS
r177 r3439 23 23 24 24 - 1.03 (2007-01-26) : 25 25 26 26 - Can now accept several requests concurrently, which may 27 27 help with terminal servers. 28 28 29 29 - Fixed a focus problem. 30 30 31 31 - Rewrote the tests/test.py program to give a better 32 32 experience to testers. 33 33 34 34 - 1.02 (2006-06-07) : 35 35 36 36 - Added the --cache command line option to specify the time in 37 37 seconds during which input forms' content will be cached. 38 38 This allows people to avoid retyping their username and 39 39 password for each print job, for example. 40 40 41 41 - Doesn't display the Quit menu anymore if not allowed. 42 43 - Doesn't display the ugly traceback anymore when the client 42 43 - Doesn't display the ugly traceback anymore when the client 44 44 disconnects before the server has sent the answer back 45 45 (pknotify --timeout). 46 46 47 47 - 1.01 (2006-05-01) : 48 49 - Now accepts command line options. 50 48 49 - Now accepts command line options. 50 51 51 - Less ugly when run under *nix. 52 52 53 53 - Debug mode off by default. 54 55 - 1.00 (2006-03-23) : 56 54 55 - 1.00 (2006-03-23) : 56 57 57 - First release -
pykoticon/trunk/README
r176 r3439 22 22 PyKotIcon is a cross-platform client-side helper for PyKota. 23 23 24 It is meant to be launched whenever the user logs in, and stay in 25 the taskbar (depending on the client operating system) until the 26 user closes his session. 27 24 It is meant to be launched whenever the user logs in, and stay in 25 the taskbar (depending on the client operating system) until the 26 user closes his session. 27 28 28 Installation : 29 29 30 30 * GNU/Linux and similar : 31 31 32 32 $ cd pykoticon 33 33 $ python setup.py install 34 34 35 35 Then modify your .xsession file, or the appropriate file depending 36 36 on your desktop environment, to ensure that the pykoticon command 37 37 is launched in the background each time your X Window session 38 38 starts. 39 39 40 40 You MUST pass the list of hostnames or IP addresses from which 41 41 PyKotIcon should accept incoming connexions on pykoticon's … … 44 44 hostnames or IP addresses of ALL print servers on pykoticon's 45 45 command line. 46 46 47 47 NB : `pykoticon --help` will give you hints about the expected 48 48 command line parameters. 49 50 * MS Windows : 51 52 Download pykoticon-x.yy.zip from 53 49 50 * MS Windows : 51 52 Download pykoticon-x.yy.zip from 53 54 54 http://www.pykota.com/software/pykoticon/download/tarballs/ 55 56 Unzip it into a directory of its own. I usually unzip it into 55 56 Unzip it into a directory of its own. I usually unzip it into 57 57 /var/lib/samba/netlogon/pykoticon/ 58 58 59 59 Modify the PYKOTICON.VBS file to include the list of authorized 60 60 print servers and change other parameters as needed, as explained 61 61 in the GNU/Linux section above. 62 62 63 63 Ensure that PYKOTICON.VBS is executed each time an user logs 64 64 in. The easiest way to do this is in STARTUP.CMD : 65 65 66 66 --- CUT --- 67 67 SET PATH=%PATH%;\\MYSERVER\NETLOGON\PYKOTICON\ 68 \\MYSERVER\NETLOGON\PYKOTICON\PYKOTICON.VBS 68 \\MYSERVER\NETLOGON\PYKOTICON\PYKOTICON.VBS 69 69 --- CUT --- 70 70 71 71 NB : if you launch PYKOTICON.EXE directly instead of from 72 PYKOTICON.VBS, a small but disturbing window may appear on 72 PYKOTICON.VBS, a small but disturbing window may appear on 73 73 the screen. 74 74 … … 84 84 independant of PyKota, and can be used from any application 85 85 which can do remote procedure calls over XML-RPC. 86 86 87 87 PyKotIcon exposes 4 of its methods over XML-RPC, here they are : 88 88 89 89 - nop : 90 90 91 91 This methods does exactly nothing :) 92 92 93 93 - Input : No argument. 94 94 95 95 - Output : returns the True boolean value. 96 97 - quitApplication : 98 96 97 - quitApplication : 98 99 99 This method causes the PyKotIcon application to exit. 100 100 101 101 - Input : No argument. 102 102 103 103 - Output : returns the True boolean value. 104 105 - showDialog : 106 104 105 - showDialog : 106 107 107 This methods displays an informational message, and returns 108 108 the choice the user made, if any. 109 110 - Input : 111 112 - message : a Binary XML-RPC object representing an UTF-8 encoded 113 character string which will be displayed to the end user. 114 This string can contain literal "\n" sequences which will 109 110 - Input : 111 112 - message : a Binary XML-RPC object representing an UTF-8 encoded 113 character string which will be displayed to the end user. 114 This string can contain literal "\n" sequences which will 115 115 be automatically expanded into line breaks by PyKotIcon. 116 117 - confirmation : a boolean value indicating if the user will 116 117 - confirmation : a boolean value indicating if the user will 118 118 be given the choice to valid or cancel (True), or only 119 119 to valid (False) the dialog box. 120 121 - Output : 122 120 121 - Output : 122 123 123 - the literal string "OK" if the user clicked on the OK button, 124 124 else the literal string "CANCEL". The latter is only possible 125 125 if the method was called with its second parameter set to 126 126 True. 127 128 - askDatas : 129 127 128 - askDatas : 129 130 130 This method can generate an input form and return what the user 131 131 entered in the different fields. 132 132 133 133 - Input : 134 135 - An array of labels, one label per input field in the 134 135 - An array of labels, one label per input field in the 136 136 form to be created. Each label in the list is passed as 137 137 a Binary XML-RPC object representing an UTF-8 encoded 138 138 character string. 139 139 140 140 - An array of variables names, one name per input field in 141 141 the form to be created. Each name in the list is passed 142 as an ASCII encoded character string. 142 as an ASCII encoded character string. 143 143 IMPORTANT : if one of these names is 'password' then this 144 particular field's input box will be visually protected 144 particular field's input box will be visually protected 145 145 with * in place of the characters typed during input. 146 147 - An associative array (e.g. Python mapping) of initial values. 146 147 - An associative array (e.g. Python mapping) of initial values. 148 148 Each key is a variable name which must be present in the list 149 149 above, and each value is a possibly empty initial content, 150 which will be passed as a Binary XML-RPC object representing 150 which will be passed as a Binary XML-RPC object representing 151 151 an UTF-8 encoded character string. 152 152 153 153 - Output : 154 154 155 155 - An associative array (e.g. Python mapping) containing the 156 156 variables names as keys and the variables' contents as 157 157 values in the following format : 158 158 159 159 - Each key is an ASCII encoded character string representing 160 the name of a variable to ask which was passed from the 160 the name of a variable to ask which was passed from the 161 161 caller. 162 163 - Each value is a Binary XML-RPC object representing an UTF-8 162 163 - Each value is a Binary XML-RPC object representing an UTF-8 164 164 encoded character string, itself being the result of user 165 165 input in the form's field for this particular variable. … … 173 173 In this case, all the other values are empty strings 174 174 anyway. 175 176 177 IMPORTANT : PyKotIcon doesn't currently support encrypted connexions, 175 176 177 IMPORTANT : PyKotIcon doesn't currently support encrypted connexions, 178 178 so if you're afraid of sensitive information flying in the clear 179 over the nework, you should probably install a transparent secure 179 over the nework, you should probably install a transparent secure 180 180 tunneling software like stunnel on both sides of each connection. 181 181 182 182 ==================================================================== 183 183 184 184 Please e-mail bugs to the PyKota mailing list at : pykota@librelogiciel.com 185 185 or to the main author at : alet@librelogiciel.com (Jerome Alet) -
pykoticon/trunk/setup.py
r176 r3439 1 1 #! /usr/bin/env python 2 # -*- coding: ISO-8859-15 -*-2 # -*- coding: iso-8859-15 -*- 3 3 4 4 """Packaging and installation script for PyKotIcon.""" … … 16 16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 17 # GNU General Public License for more details. 18 # 18 # 19 19 # You should have received a copy of the GNU General Public License 20 20 # along with this program; if not, write to the Free Software … … 36 36 sys.stderr.write("py2exe is not installed ! ABORTING.\n") 37 37 sys.exit(-1) 38 else : 38 else : 39 39 directory = os.sep.join(["share", "pykoticon"]) 40 40 mandir = os.sep.join(["share", "man", "man1"]) 41 manpages = glob.glob(os.sep.join(["man", "*.1"])) 41 manpages = glob.glob(os.sep.join(["man", "*.1"])) 42 42 initialdatafiles = [(mandir, manpages)] 43 43 withPy2EXE = False 44 else : 44 else : 45 45 directory = "." 46 46 initialdatafiles = [] … … 48 48 49 49 config = imp.load_source("config", os.path.join("bin", "pykoticon")) 50 setupDictionary = { "name" : "pykoticon", 50 setupDictionary = { "name" : "pykoticon", 51 51 "version" : config.__version__, 52 52 "license" : config.__license__, -
pykoticon/trunk/tests/test.py
r176 r3439 1 1 #! /usr/bin/env python 2 # -*- coding: ISO-8859-15 -*-2 # -*- coding: iso-8859-15 -*- 3 3 4 4 # PyKotIcon - Client side helper for PyKota and other applications … … 14 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 15 # GNU General Public License for more details. 16 # 16 # 17 17 # You should have received a copy of the GNU General Public License 18 18 # along with this program; if not, write to the Free Software … … 43 43 # Opens the connection to the PyKotIcon server : 44 44 server = xmlrpclib.ServerProxy("http://%s:%s" % (arguments[0], arguments[1])) 45 45 46 46 # Now display something on the PyKotIcon host : 47 47 message1 = "You are about to test PyKotIcon\n\nPyKotIcon is really great software !" 48 48 server.showDialog(xmlrpclib.Binary(message1.encode("UTF-8")), False) 49 50 # Now ask the end user if he really wants to do this : 49 50 # Now ask the end user if he really wants to do this : 51 51 message2 = "Are you sure you want to do this ?" 52 52 result = server.showDialog(xmlrpclib.Binary(message2.encode("UTF-8")), True) 53 53 print "The remote user said : %s" % result 54 54 55 55 # Displays the answer back : 56 56 answer = "You have clicked on the %s button" % result 57 57 server.showDialog(xmlrpclib.Binary(answer.encode("UTF-8")), False) 58 59 # Now we will ask some datas : 58 59 # Now we will ask some datas : 60 60 result = server.askDatas([xmlrpclib.Binary(v) for v in ["Username", "Password", "Country"]], \ 61 61 ["username", "password", "country"], \ … … 68 68 answer = "You answered :\n%s" % "\n".join(["%s => '%s'" % (k, v.data) for (k, v) in result.items() if k != "isValid"]) 69 69 server.showDialog(xmlrpclib.Binary(answer.encode("UTF-8")), False) 70 else : 70 else : 71 71 print "The answers are not valid." 72 73 # Now do nothing : 72 73 # Now do nothing : 74 74 server.nop() 75 75 76 76 # Finally we will cause PyKotIcon to die 77 77 message3 = "As soon as you'll click on the button below, PyKotIcon will die." 78 78 server.showDialog(xmlrpclib.Binary(message3.encode("UTF-8")), False) 79 79 server.quitApplication() 80 80 81 81 # That's all folks ! 82 82 print 83 83 print "This demo is finished. Did you like it ?" 84 84 85 85 if __name__ == "__main__" : 86 86 if len(sys.argv) < 3 : 87 87 sys.stderr.write("usage : %s pykoticon_hostname_or_ip_address pykoticon_TCPPort\n" % sys.argv[0]) 88 else : 88 else : 89 89 try : 90 90 main(sys.argv[1:]) 91 except socket.error, msg : 91 except socket.error, msg : 92 92 sys.stderr.write("ERROR : Network error : %s\n" % msg) 93 93 sys.stderr.write("Are you sure that PyKotIcon is running and accepts incoming connections ?\n") 94 94 -
pykoticon/trunk/TODO
r181 r3439 22 22 TODO, in no particular order : 23 23 24 - Add a way to provide an additional text when using 24 - Add a way to provide an additional text when using 25 25 pknotify --ask. 26 27 - Don't display anything or even initialize the graphical interface 26 27 - Don't display anything or even initialize the graphical interface 28 28 until an incoming connection is received : this will allow 29 29 a single instance to be launched and choose its display 30 30 at connection time for use on terminal servers. 31 32 - Add a command line parameter to control the window's modal/modeless 31 32 - Add a command line parameter to control the window's modal/modeless 33 33 mode. The default will not be modal in any case. 34 34 35 35 - SSL or other encryption support. 36 36 37 37 - Fix focus problem reported by some people. 38 38 39 39 ============================================================ 40 40