Personal wiki notebook (not under development)

luminotes.py 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #!/usr/bin/python
  2. import os
  3. import sys
  4. import stat
  5. import socket
  6. import os.path
  7. import urllib2 as urllib
  8. import optparse
  9. import cherrypy
  10. import webbrowser
  11. from controller.Database import Database
  12. from controller.Schema_upgrader import Schema_upgrader
  13. from controller.Root import Root
  14. from config import Common
  15. from config.Version import VERSION
  16. INITIAL_SOCKET_TIMEOUT_SECONDS = 1
  17. SOCKET_TIMEOUT_SECONDS = 60
  18. def change_to_main_dir():
  19. """
  20. Change to the directory where the executable / main script is located.
  21. """
  22. if hasattr( sys, "frozen" ):
  23. path = os.path.dirname( unicode( sys.executable, sys.getfilesystemencoding() ) )
  24. else:
  25. path = os.path.dirname( unicode( __file__, sys.getfilesystemencoding() ) )
  26. if path:
  27. os.chdir( path )
  28. def main( options ):
  29. change_to_main_dir()
  30. cherrypy.config.update( Common.settings )
  31. if options.development:
  32. from config import Development
  33. settings = Development.settings
  34. elif options.desktop:
  35. from config import Desktop
  36. settings = Desktop.settings
  37. else:
  38. from config import Production
  39. settings = Production.settings
  40. cherrypy.config.update( settings )
  41. # Don't launch web browser if -w flag is set
  42. if options.no_webbrowser:
  43. launch_browser = False
  44. else:
  45. launch_browser = cherrypy.config.configMap[ u"global" ].get( u"luminotes.launch_browser" )
  46. socket.setdefaulttimeout( INITIAL_SOCKET_TIMEOUT_SECONDS )
  47. port_filename = cherrypy.config.configMap[ u"global" ].get( u"luminotes.port_file" )
  48. socket_port = cherrypy.config.configMap[ u"global" ].get( u"server.socket_port" )
  49. existing_socket_port = port_filename and os.path.exists( port_filename ) and file( port_filename ).read() or socket_port
  50. server_url = u"http://localhost:%s/" % existing_socket_port
  51. server_present = True
  52. # if requested, attempt to shutdown an existing server and exit
  53. if options.kill:
  54. try:
  55. urllib.urlopen( "%sshutdown" % server_url )
  56. except urllib.URLError:
  57. pass
  58. sys.exit( 0 )
  59. # check to see if the server is already running
  60. try:
  61. urllib.urlopen( "%sping" % server_url )
  62. except urllib.URLError:
  63. server_present = False
  64. if server_present is True:
  65. print "Luminotes server is already running. aborting"
  66. if launch_browser is True:
  67. webbrowser.open_new( server_url )
  68. sys.exit( 0 )
  69. server_url = u"http://localhost:%s/" % socket_port
  70. # remove the existing log files, if any
  71. try:
  72. log_access_file = cherrypy.config.configMap[ u"global" ].get( u"server.log_access_file" )
  73. if log_access_file:
  74. os.remove( log_access_file )
  75. except OSError:
  76. pass
  77. try:
  78. log_file = cherrypy.config.configMap[ u"global" ].get( u"server.log_file" )
  79. if log_file:
  80. os.remove( log_file )
  81. except OSError:
  82. pass
  83. socket.setdefaulttimeout( SOCKET_TIMEOUT_SECONDS )
  84. database = Database(
  85. host = cherrypy.config.configMap[ u"global" ].get( u"luminotes.db_host" ),
  86. ssl_mode = cherrypy.config.configMap[ u"global" ].get( u"luminotes.db_ssl_mode" ),
  87. )
  88. # if necessary, upgrade the database schema to match this current version of the code
  89. schema_upgrader = Schema_upgrader( database )
  90. schema_upgrader.upgrade_schema( to_version = VERSION )
  91. cherrypy.lowercase_api = True
  92. root = Root( database, cherrypy.config.configMap )
  93. cherrypy.root = root
  94. cherrypy.server.start_with_callback( callback, ( log_access_file, log_file, server_url, port_filename, socket_port, launch_browser ) )
  95. def callback( log_access_file, log_file, server_url, port_filename, socket_port, launch_browser = False ):
  96. # record our listening socket port
  97. if port_filename:
  98. port_file = file( port_filename, "w" )
  99. os.chmod( port_filename, stat.S_IRUSR | stat.S_IWUSR )
  100. port_file.write( "%s" % socket_port )
  101. port_file.close()
  102. # this causes cherrypy to create the access log
  103. if log_access_file:
  104. try:
  105. urllib.urlopen( "%sping" % server_url )
  106. except urllib.URLError:
  107. pass
  108. # give the cherrypy log files appropriate permissions
  109. if log_access_file and os.path.exists( log_access_file ):
  110. os.chmod( log_access_file, stat.S_IRUSR | stat.S_IWUSR )
  111. if log_file and os.path.exists( log_file ):
  112. os.chmod( log_file, stat.S_IRUSR | stat.S_IWUSR )
  113. if launch_browser:
  114. webbrowser.open_new( server_url )
  115. if __name__ == "__main__":
  116. # sys.frozen is from py2exe
  117. desktop_default = hasattr( sys, "frozen" )
  118. parser = optparse.OptionParser(
  119. usage = "usage: %prog [OPTIONS]\n" +
  120. " OR: %prog --help",
  121. version = VERSION,
  122. )
  123. parser.add_option(
  124. "-l", "--desktop",
  125. dest = "desktop",
  126. action = "store_true",
  127. default = desktop_default,
  128. help = "Run in Desktop mode %s" %
  129. ( "(DEFAULT)" if desktop_default else "" ),
  130. )
  131. parser.add_option(
  132. "-s", "--server",
  133. dest = "desktop",
  134. action = "store_false",
  135. help = "Run in Server mode %s" %
  136. ( "(DEFAULT)" if not desktop_default else "" ),
  137. )
  138. parser.add_option(
  139. "-d", "--developement",
  140. dest = "development",
  141. action = "store_true",
  142. help = "Run in Development mode",
  143. )
  144. parser.add_option(
  145. "-k", "--kill",
  146. dest = "kill",
  147. action = "store_true",
  148. help = "Attempt to shutdown existing server and exit",
  149. )
  150. parser.add_option(
  151. "-w", "--no_webbrowser",
  152. dest = "no_webbrowser",
  153. action = "store_true",
  154. help = "Don't autolaunch web browser in Desktop mode",
  155. )
  156. ( options, args ) = parser.parse_args()
  157. if args != []:
  158. parser.error( "Unrecognised options: %s" % " ".join( args ) )
  159. main(options)