[wxPython-users] Distributing a wxpy app - central server or each workstation

Nicolas BRICHE nbriche at free.fr
Thu Mar 1 10:23:19 PST 2007


Michael Hipp a écrit :

> Nicolas, would you be interested in sharing your complete version? I've been 
> looking to do exactly this and it appears as if you've already solved it.
> 
> Thanks,
> Michael

Sure.  I just hope this won't be _too_ off topic for this list...

Note that this is a horrible kludge, mostly because I had to do it in 
emergency (as in, I had one and a half hour to think of, code, test and 
deploy a solution).

Anyways.

The application (named PASTEL - yes, MIPIH, this means YOU) already uses 
a "pastel.bat" launcher in its original form.  I inserted the "CALL" 
line at the very beginning of the launcher.  This is to minimize the 
changes in the launcher: in case the MIPIH decides to change something 
in it, I'll just have to add that one line again.

<c:\pastel\config\pastel.bat>
********[BEGIN]**************
@echo off

CALL c:\pastel\config\updater.bat

rem -- Everything after is the original launcher:

SET CONVERGENCE=c:\pastel

SET PATH=c:\ora817\bin

rem -- Lots of other init stuff ---

rem -- Finally, launching the app:
MENUG.EXE

*********[END]***************


<updater.bat>
********[BEGIN]**************
@echo off

echo > c:\pastel\temoin.maj
start c:\pastel\notice\notice.exe

xcopy \\peron08\installs$\pastel c:\pastel /H /Y /E /D /R
del c:\pastel\temoin.maj

*********[END]***************


Notice.exe is a small Python+Tcl/Tk script that just runs until 
temoin.maj is deleted, i.e. until the xcopy ends.  I've traducted the 
comments and labels for your convenience (and cleaned some):

<notice.py>
********[BEGIN]**************
## -*- coding: iso8859-15 -*-
import Tkinter, os.path
import os, os.path

# Takes the tcl/tk library from local subdirectory if available.
os.environ['TCL_LIBRARY'] = 'c:/pastel/notice/tcl8.4'
os.environ['TK_LIBRARY'] =  'c:/pastel/notice/tk8.4'


class Application(Tkinter.Frame):
	status=0
	activity_string=["|","/","---","\\"]
	def __init__(self, master=None):
		Tkinter.Frame.__init__(self, master)
		self.grid() # Prepares the main frame
		self.createWidgets() # Creates the window's contents
		self.poll() # Timer, detects temoin.maj's presence
		self.activity() # Timer, changes self.lactivity's label 					# 
(rotating effect)

	def createWidgets(self):
		self.label1 = Tkinter.Label ( self, text="Updating Pastel...", 
padx=10, pady=10)
		self.label1.grid()
		self.label2 = Tkinter.Label ( self, text="Please wait..." )
		self.label2.grid()
		self.lactivity = Tkinter.Label ( self, text="|", padx=10, pady=10)
		self.lactivity.grid()
		
	def poll(self):
		if not os.path.exists("c:/pastel/temoin.maj"): self.quit()
		self.after(100, self.poll)

	def activity(self):
		self.lactivity["text"]=self.activity_string[self.status]
		self.status+=1
		if self.status==4: self.status=0
		self.after(500, self.activity)


app = Application()

# Creating the window
app.master.title("PASTEL")
app.master.resizable ( width=False, height=False )
app.master.update_idletasks()
sw=app.master.winfo_screenwidth()
sh=app.master.winfo_screenheight()
w=app.master.winfo_width()
h=app.master.winfo_height()
app.master.geometry("%dx%d+%d+%d" % ( w, h, (sw-h)/2, (sh-h)/2 ) )
app.master.focus_force()

app.mainloop()

*********[END]***************

I've put in c:/pastel/notice: the executable, the python DLL, and the 
tcl/tk runtime (DLLs+directories).

Yup, I'm aware that this is not the most beautiful code ever.  More 
precisely, I'm still thinking about how I can get rid of the need for 
xcopy (and thus for a Windows share), because:

a) it's not very secure (hah!), and

b) since I make xcopy rely on file dates, I've had some problems when 
switching to DST (where xcopy somehow decides that the server version is 
one hour off and so updates everything).  Unfortunately, I cant take the 
risk of not updating a file that keeps its size in an updated version. 
So the date switch stays.

The "proper" solution I have in mind is way heavier to implement, but 
adds some nifty things for an administrator: the client would compare 
its tree and a list of its files' MD5 hashes with the server's current 
tree and MD5 list, and updates if anything's different.  This list would 
be stored in some sort of database (SQLite or Mysql/PostgeSQL, depending 
on whether the target application already uses a networked database) 
along with a log table, so that I know which client is up-to-date, which 
one isn't, and when they did the update.  Since PASTEL has a very large 
tree (5419 files for 344MB, including a whooping 1937 DLLs!), this would 
be faster than xcopy (which is already quite surprisingly fast) and 
generate less network traffic.  I could even choose which files to 
update, when they'll be updated, etc.

In theory, it wouldn't be very hard to do.  In practice, I'd have to 
find some time to do it...

Hm.  This could be a work for wxPython.  The administration part, I mean.

(Yes, this was a shameful attempt to stay On Topic.)

Oh, and if any MIPIH developer reads this list: please, do implement a 
proper solution.  I'm really begging you, here.  My current solution is 
fine for our core LAN (60 clients on 10/100Mb Ethernet, and the 10Mb/s 
is somewhat stretching it when the update's 30MB).  But it's point blank 
unthinkable for our WAN (still 10 clients or so on a 512/128Kb ADSL VPN).


I hope this will help you some.  Nothing here is really copyright- or 
patent-worthy, so pick as you choose.

N.

-- 

"If you try to stay sane in life, it'll just
drive you crazy.  So, you may as well go crazy
now and have fun with life."
--MegaZone





More information about the wxpython-users mailing list