Package gluon :: Module widget
[hide private]
[frames] | no frames]

Source Code for Module gluon.widget

  1  #!/bin/python2.5 
  2   
  3  """ 
  4  This file is part of the web2py Web Framework (Copyrighted, 2007-2008) 
  5  Developed in Python by Massimo Di Pierro <mdipierro@cs.depaul.edu> 
  6  """ 
  7   
  8  import sys, cStringIO 
  9   
 10  if sys.version[:3]!='2.5': 
 11      sys.stderr.write('Warning: web2py requires Python 2.5 but, instead, you are running:\n%s' % sys.version) 
 12   
 13  ProgramName="web2py Enterprise Web Framework" 
 14  ProgramAuthor='Created by Massimo Di Pierro, Copyright 2007-2008' 
 15  ProgramVersion=open('VERSION','r').read().strip() 
 16   
17 -class IO(object):
18 - def __init__(self):
19 self.buffer=cStringIO.StringIO()
20 - def write(self,data):
21 sys.__stdout__.write(data) 22 if hasattr(self,'callback'): self.callback(data) 23 else: self.buffer.write(data)
24 25 try: 26 import tkMessageBox, Tkinter 27 havetk=True 28 except: 29 havetk=False 30 31 print ProgramName 32 print ProgramAuthor 33 print ProgramVersion 34 35 from gluon.main import HttpServer, save_password 36 from gluon.fileutils import tar, untar 37 from optparse import * 38 from gluon.shell import run 39 import time, webbrowser, thread, re, cStringIO, os, stat, socket, signal, math 40
41 -def try_start_browser(url):
42 try: webbrowser.open(url) 43 except: print 'warning: unable to detect your browser'
44
45 -def start_browser(ip,port):
46 print 'please visit:' 47 print '\thttp://%s:%s/welcome' % (ip,port) 48 print 'starting browser...in 5 seconds' 49 time.sleep(5) 50 try_start_browser('http://%s:%s/welcome'%(ip,port))
51
52 -def presentation(root):
53 root.withdraw() 54 dx=root.winfo_screenwidth() 55 dy=root.winfo_screenheight() 56 dialog=Tkinter.Toplevel(root) 57 dialog.geometry('%ix%i+%i+%i' % (400,300,dx/2-200, dy/2-150)) 58 dialog.overrideredirect(1) 59 dialog.focus_force() 60 canvas=Tkinter.Canvas(dialog, background='white', width=400, height=300) 61 canvas.pack() 62 root.update() 63 for counter in xrange(5): 64 if counter is 0: 65 canvas.create_text(200,50, text='Welcome to ...', 66 font=('Helvetica',12), 67 anchor=Tkinter.CENTER, fill='#195866') 68 elif counter is 1: 69 canvas.create_text(200,130, text=ProgramName, 70 font=('Helvetica',18), 71 anchor=Tkinter.CENTER, fill='#FF5C1F') 72 elif counter is 2: 73 canvas.create_text(200,170, 74 text=ProgramAuthor, 75 font=('Helvetica',12), 76 anchor=Tkinter.CENTER, fill='#195866') 77 elif counter is 3: 78 canvas.create_text(200,250, text=ProgramVersion, 79 font=('Helvetica',12), 80 anchor=Tkinter.CENTER, fill='#195866') 81 else: 82 dialog.destroy() 83 return 84 root.update() 85 time.sleep(1.5) 86 return root
87
88 -class web2pyDialog(object):
89 - def __init__(self,root,options):
90 root.title('web2py server') 91 self.root=Tkinter.Toplevel(root) 92 self.options=options 93 self.menu=Tkinter.Menu(self.root) 94 servermenu = Tkinter.Menu(self.menu,tearoff=0) 95 httplog=os.path.join(os.getcwd(),'httpserver.log') 96 servermenu.add_command(label='View httpserver.log', 97 command=lambda:try_start_browser(httplog)) 98 servermenu.add_command(label='Quit (pid:%i)' % os.getpid(), 99 command=self.quit) 100 self.menu.add_cascade(label="Server", menu=servermenu) 101 102 self.pagesmenu = Tkinter.Menu(self.menu,tearoff=0) 103 self.menu.add_cascade(label="Pages", menu=self.pagesmenu) 104 105 helpmenu = Tkinter.Menu(self.menu,tearoff=0) 106 helpmenu.add_command(label="Home Page", command=lambda: try_start_browser('http://www.web2py.com')) 107 helpmenu.add_command(label="About", command=lambda:tkMessageBox.showinfo('About web2py','%s\n%s\n%s'%(ProgramName,ProgramAuthor,ProgramVersion))) 108 self.menu.add_cascade(label="Info", menu=helpmenu) 109 110 self.root.config(menu=self.menu) 111 self.root.protocol("WM_DELETE_WINDOW", self.quit) 112 sticky=Tkinter.NW 113 Tkinter.Label(self.root, text="Choose a password:",justify=Tkinter.LEFT).grid(row=0,column=0,sticky=sticky) 114 self.password = Tkinter.Entry(self.root,show='*') 115 self.password.grid(row=0, column=1,sticky=sticky) 116 Tkinter.Label(self.root, text="Running from host:",justify=Tkinter.LEFT).grid(row=1,column=0,sticky=sticky) 117 self.ip = Tkinter.Entry(self.root) 118 self.ip.insert(Tkinter.END,'127.0.0.1') 119 self.ip.grid(row=1, column=1,sticky=sticky) 120 Tkinter.Label(self.root, text="Running from port:",justify=Tkinter.LEFT).grid(row=2,column=0,sticky=sticky) 121 self.port_number = Tkinter.Entry(self.root) 122 self.port_number.insert(Tkinter.END,'8000') 123 self.port_number.grid(row=2, column=1,sticky=sticky) 124 self.canvas=Tkinter.Canvas(self.root,width=300,height=100,bg='black') 125 self.canvas.grid(row=3,column=0,columnspan=2) 126 self.canvas.after(1000,self.update_canvas) 127 frame=Tkinter.Frame(self.root) 128 frame.grid(row=4,column=0,columnspan=2) 129 self.button_start=Tkinter.Button(frame,text='start server',command=self.start) 130 self.button_start.grid(row=0, column=0) 131 self.button_stop=Tkinter.Button(frame,text='stop server',command=self.stop) 132 self.button_stop.grid(row=0, column=1) 133 self.button_stop.configure(state='disabled')
134
135 - def update(self,text):
136 try: 137 self.text.configure(state='normal') 138 self.text.insert('end',text) 139 self.text.configure(state='disabled') 140 except: pass ### this should only happen in case app is destroyed
141 - def connect_pages(self):
142 for file in os.listdir('applications/'): 143 if os.access('applications/%s/__init__.py' % file,os.R_OK): 144 url=self.url+'/'+file 145 self.pagesmenu.add_command(label=url, command=lambda u=url:try_start_browser(u))
146 - def quit(self):
147 try: self.server.stop() 148 except: pass 149 self.root.destroy() 150 sys.exit()
151 - def error(self,message):
152 tkMessageBox.showerror("web2py start server",message) 153 return
154 - def start(self):
155 password=self.password.get() 156 if not password: 157 self.error('no password, no web admin interface') 158 ip=self.ip.get() 159 if ip and not re.compile('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}').match(ip): 160 return self.error('invalid host ip address') 161 try: port=int(self.port_number.get()) 162 except: 163 return self.error('invalid port number') 164 self.url='http://%s:%s' % (ip,port) 165 self.connect_pages() 166 self.button_start.configure(state='disabled') 167 try: 168 options=self.options 169 self.server=HttpServer(ip,port,password, 170 pid_filename=options.pid_filename, 171 log_filename=options.log_filename, 172 ssl_certificate=options.ssl_certificate, 173 ssl_private_key=options.ssl_private_key, 174 numthreads=options.numthreads, 175 server_name=options.server_name, 176 request_queue_size=options.request_queue_size, 177 timeout=options.timeout, 178 shutdown_timeout=options.shutdown_timeout, 179 path=options.folder) 180 thread.start_new_thread(self.server.start,()) 181 except BaseException, e: 182 self.button_start.configure(state='normal') 183 return self.error(str(e)) 184 self.button_stop.configure(state='normal') 185 thread.start_new_thread(start_browser,(ip,port)) 186 self.password.configure(state='readonly') 187 self.ip.configure(state='readonly') 188 self.port_number.configure(state='readonly')
189 - def stop(self):
190 self.button_start.configure(state='normal') 191 self.button_stop.configure(state='disabled') 192 self.password.configure(state='normal') 193 self.ip.configure(state='normal') 194 self.port_number.configure(state='normal') 195 self.server.stop()
196 - def update_canvas(self):
197 try: 198 t1=os.stat('httpserver.log')[stat.ST_SIZE] 199 except: 200 self.canvas.after(1000, self.update_canvas ) 201 return 202 try: 203 file=open('httpserver.log','r') 204 file.seek(self.t0) 205 data=file.read(t1-self.t0) 206 self.p0=self.p0[1:]+[10+90.0/math.sqrt(1+data.count('\n'))] 207 for i in xrange(len(self.p0)-1): 208 c=self.canvas.coords(self.q0[i]) 209 self.canvas.coords(self.q0[i], 210 (c[0],self.p0[i],c[2],self.p0[i+1])) 211 self.t0=t1 212 except BaseException, e: 213 self.t0=time.time() 214 self.t0=t1 215 self.p0=[100]*300 216 self.q0=[self.canvas.create_line(i,100,i+1,100,fill='green') for i in xrange(len(self.p0)-1)] 217 self.canvas.after(1000, self.update_canvas )
218
219 -def console():
220 usage="""python web2py.py""" 221 description="""web2py Web Framework startup script. ATTENTION: unless a password is specified (-a 'passwd') web2py will attempt to run a GUI. In this case command line options are ignored.""" 222 parser=OptionParser(usage,None,Option,ProgramVersion) 223 parser.description=description 224 parser.add_option('-i','--ip',default='127.0.0.1',dest='ip', 225 help='the ip address of the server (127.0.0.1)') 226 parser.add_option('-p','--port',default='8000',dest='port', 227 help='the port for of server (8000)') 228 parser.add_option('-a','--password',default='<ask>',dest='password', 229 help='the password to be used for administration'+\ 230 "(use -a '<recycle>' to reuse the last password)") 231 parser.add_option('-u','--upgrade',default='no',dest='upgrade', 232 help='upgrade applications') 233 parser.add_option('-c','--ssl_certificate',default='', 234 dest='ssl_certificate', 235 help='file that contains ssl certificate') 236 parser.add_option('-k','--ssl_private_key',default='', 237 dest='ssl_private_key', 238 help='file that contains ssl private key') 239 parser.add_option('-d','--pid_filename',default='httpserver.pid', 240 dest='pid_filename', 241 help='file where to store the pid of the server') 242 parser.add_option('-l','--log_filename',default='httpserver.log', 243 dest='log_filename', 244 help='file where to log connections') 245 parser.add_option('-n','--numthreads',default='10', 246 dest='numthreads', 247 help='number of threads') 248 parser.add_option('-s','--server_name',default=socket.gethostname(), 249 dest='server_name', 250 help='the server name for the web server') 251 parser.add_option('-q','--request_queue_size',default='5', 252 dest='request_queue_size', 253 help='max number of queued requests when server unavailable') 254 parser.add_option('-o','--timeout',default='10', 255 dest='timeout', 256 help='timeout for individual request') 257 parser.add_option('-z','--shutdown_timeout',default='5', 258 dest='shutdown_timeout', 259 help='timeout on shutdown of server') 260 parser.add_option('-f','--folder',default=os.getcwd(), 261 dest='folder', 262 help='the folder where to run web2py') 263 parser.add_option('-S', '--shell', 264 dest='shell', metavar='APPNAME', 265 help='run web2py in interactive shell or IPython(if installed) with specified appname') 266 parser.add_option('-P', '--plain', action='store_true', default=False, 267 dest='plain', 268 help='only use plain python shell, should be used with --shell option') 269 parser.add_option('-M', '--import_models', action='store_true', default=False, 270 dest='import_models', 271 help='auto import model files, default is False, should be used with --shell option') 272 parser.add_option('-R', '--run', dest='run', metavar='PYTHON_FILE', default='', 273 help='run PYTHON_FILE in web2py environment, should be used with --shell option') 274 (options, args) = parser.parse_args() 275 if not os.access('applications', os.F_OK): os.mkdir('applications') 276 if not os.access('deposit', os.F_OK): os.mkdir('deposit') 277 if not os.access('applications/__init__.py',os.F_OK) or options.upgrade=='yes': 278 print 'unpacking apps, this may take a few minutes...' 279 if not os.access('applications/admin', os.F_OK): 280 os.mkdir('applications/admin') 281 untar('admin.tar','applications/admin/') 282 if not os.access('applications/welcome', os.F_OK): 283 os.mkdir('applications/welcome') 284 untar('welcome.tar','applications/welcome/') 285 if not os.access('applications/examples', os.F_OK): 286 os.mkdir('applications/examples') 287 untar('examples.tar','applications/examples/') 288 open('applications/__init__.py','w').write('') 289 print 'default applications are now installed' 290 else: 291 print 'default applications appear to be installed already' 292 return options
293
294 -def start():
295 options=console() 296 if options.shell: 297 run(options.shell, plain=options.plain, import_models=options.import_models, 298 startfile=options.run) 299 return 300 root=None 301 if options.password=='<ask>' and havetk: 302 try: root=Tkinter.Tk() 303 except: pass 304 if root: 305 root.focus_force() 306 presentation(root) 307 master=web2pyDialog(root,options) 308 signal.signal(signal.SIGTERM,lambda a,b: master.quit()) 309 try: root.mainloop() 310 except: master.quit() 311 sys.exit() 312 if not root and options.password=='<ask>': 313 options.password=raw_input('choose a password:') 314 if not options.password: 315 print 'no password, no admin interface' 316 ip,port=options.ip,int(options.port) 317 print 'please visit:' 318 print '\thttp://%s:%s/welcome' % (ip,port) 319 print 'use "kill -SIGTERM %i" to shutdown the web2py server' % os.getpid() 320 server=HttpServer(ip=ip,port=port,password=options.password, 321 pid_filename=options.pid_filename, 322 log_filename=options.log_filename, 323 ssl_certificate=options.ssl_certificate, 324 ssl_private_key=options.ssl_private_key, 325 numthreads=options.numthreads, 326 server_name=options.server_name, 327 request_queue_size=options.request_queue_size, 328 timeout=options.timeout, 329 shutdown_timeout=options.shutdown_timeout, 330 path=options.folder) 331 try: server.start() 332 except KeyboardInterrupt: server.stop()
333