mirror of
				https://github.com/kovidgoyal/calibre.git
				synced 2025-10-31 10:37:00 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			129 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/env python
 | |
| # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
 | |
| 
 | |
| __license__   = 'GPL v3'
 | |
| __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
 | |
| __docformat__ = 'restructuredtext en'
 | |
| 
 | |
| import subprocess, tempfile, os, time, sys, telnetlib
 | |
| from threading import RLock
 | |
| 
 | |
| from setup import Command
 | |
| 
 | |
| try:
 | |
|     from pyinotify import WatchManager, ThreadedNotifier, EventsCodes, ProcessEvent
 | |
| except:
 | |
|     wm = None
 | |
| else:
 | |
|     wm = WatchManager()
 | |
|     flags = EventsCodes.ALL_FLAGS
 | |
|     mask = flags['IN_MODIFY']
 | |
| 
 | |
|     class ProcessEvents(ProcessEvent):
 | |
| 
 | |
|         def __init__(self, command):
 | |
|             ProcessEvent.__init__(self)
 | |
|             self.command = command
 | |
| 
 | |
|         def process_default(self, event):
 | |
|             name = getattr(event,
 | |
|                     'name', None)
 | |
|             if not name:
 | |
|                 return
 | |
|             ext = os.path.splitext(name)[1]
 | |
|             reload = False
 | |
|             if ext == '.py':
 | |
|                 reload = True
 | |
|                 print
 | |
|                 print name, 'changed'
 | |
|                 self.command.kill_server()
 | |
|                 self.command.launch_server()
 | |
|                 print self.command.prompt,
 | |
|                 sys.stdout.flush()
 | |
| 
 | |
|             if reload:
 | |
|                 self.command.reload_browser(delay=1)
 | |
| 
 | |
| 
 | |
| class Server(Command):
 | |
| 
 | |
|     description = 'Run the calibre server in development mode conveniently'
 | |
| 
 | |
|     MONOCLE_PATH = '../monocle'
 | |
| 
 | |
|     def rebuild_monocole(self):
 | |
|         subprocess.check_call(['sprocketize', '-C', self.MONOCLE_PATH,
 | |
|             '-I', 'src', 'src/monocle.js'],
 | |
|             stdout=open('resources/content_server/read/monocle.js', 'wb'))
 | |
| 
 | |
|     def launch_server(self):
 | |
|         print 'Starting server...\n'
 | |
|         with self.lock:
 | |
|             self.rebuild_monocole()
 | |
|             self.server_proc = p = subprocess.Popen(['calibre-server', '--develop'],
 | |
|                     stderr=subprocess.STDOUT, stdout=self.server_log)
 | |
|             time.sleep(0.2)
 | |
|             if p.poll() is not None:
 | |
|                 print 'Starting server failed'
 | |
|                 raise SystemExit(1)
 | |
|             return p
 | |
| 
 | |
|     def kill_server(self):
 | |
|         print 'Killing server...\n'
 | |
|         if self.server_proc is not None:
 | |
|             with self.lock:
 | |
|                 if self.server_proc.poll() is None:
 | |
|                     self.server_proc.terminate()
 | |
|                 while self.server_proc.poll() is None:
 | |
|                     time.sleep(0.1)
 | |
| 
 | |
|     def watch(self):
 | |
|         if wm is not None:
 | |
|             self.notifier = ThreadedNotifier(wm, ProcessEvents(self))
 | |
|             self.notifier.start()
 | |
|             self.wdd = wm.add_watch(os.path.abspath('src'), mask, rec=True)
 | |
| 
 | |
|     def reload_browser(self, delay=0.1):
 | |
|         time.sleep(delay)
 | |
|         try:
 | |
|             t = telnetlib.Telnet('localhost', 4242)
 | |
|             t.read_until("repl>")
 | |
|             t.write('BrowserReload();')
 | |
|             t.read_until("repl>")
 | |
|             t.close()
 | |
|         except:
 | |
|             print 'Failed to reload browser'
 | |
|             import traceback
 | |
|             traceback.print_exc()
 | |
| 
 | |
|     def run(self, opts):
 | |
|         self.lock = RLock()
 | |
|         tdir = tempfile.gettempdir()
 | |
|         logf = os.path.join(tdir, 'calibre-server.log')
 | |
|         self.server_log = open(logf, 'ab')
 | |
|         self.prompt = 'Press Enter to kill/restart server. Ctrl+C to quit: '
 | |
|         print 'Server log available at:', logf
 | |
|         print
 | |
|         self.watch()
 | |
| 
 | |
|         first = True
 | |
|         while True:
 | |
|             self.launch_server()
 | |
|             if not first:
 | |
|                 self.reload_browser()
 | |
|             first = False
 | |
| 
 | |
|             try:
 | |
|                 raw_input(self.prompt)
 | |
|             except:
 | |
|                 print
 | |
|                 self.kill_server()
 | |
|                 break
 | |
|             else:
 | |
|                 self.kill_server()
 | |
|         print
 | |
| 
 | |
|         if hasattr(self, 'notifier'):
 | |
|             self.notifier.stop()
 | |
| 
 |