home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_1305 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  14.4 KB  |  385 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __license__ = 'GPL v3'
  5. __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
  6. import sys
  7. import os
  8. import time
  9. import socket
  10. import traceback
  11. from functools import partial
  12. from PyQt4.Qt import QCoreApplication, QIcon, QMessageBox, QObject, QTimer, QThread, pyqtSignal, Qt, QProgressDialog, QString, QPixmap, QSplashScreen, QApplication
  13. from calibre import prints, plugins
  14. from calibre.constants import iswindows, __appname__, isosx, DEBUG, filesystem_encoding
  15. from calibre.utils.ipc import ADDRESS, RC
  16. from calibre.gui2 import ORG_NAME, APP_UID, initialize_file_icon_provider, Application, choose_dir, error_dialog, question_dialog, gprefs
  17. from calibre.gui2.main_window import option_parser as _option_parser
  18. from calibre.utils.config import prefs, dynamic
  19. from calibre.library.database2 import LibraryDatabase2
  20. from calibre.library.sqlite import sqlite, DatabaseException
  21.  
  22. def option_parser():
  23.     parser = _option_parser('%prog [opts] [path_to_ebook]\n\nLaunch the main calibre Graphical User Interface and optionally add the ebook at\npath_to_ebook to the database.\n')
  24.     parser.add_option('--with-library', default = None, action = 'store', help = _('Use the library located at the specified path.'))
  25.     parser.add_option('--start-in-tray', default = False, action = 'store_true', help = _('Start minimized to system tray.'))
  26.     parser.add_option('-v', '--verbose', default = 0, action = 'count', help = _('Log debugging information to console'))
  27.     parser.add_option('--no-update-check', default = False, action = 'store_true', help = _('Do not check for updates'))
  28.     return parser
  29.  
  30.  
  31. def init_qt(args):
  32.     Main = Main
  33.     import calibre.gui2.ui
  34.     parser = option_parser()
  35.     (opts, args) = parser.parse_args(args)
  36.     if opts.with_library is not None:
  37.         if not os.path.exists(opts.with_library):
  38.             os.makedirs(opts.with_library)
  39.         
  40.         if os.path.isdir(opts.with_library):
  41.             prefs.set('library_path', os.path.abspath(opts.with_library))
  42.             prints('Using library at', prefs['library_path'])
  43.         
  44.     
  45.     QCoreApplication.setOrganizationName(ORG_NAME)
  46.     QCoreApplication.setApplicationName(APP_UID)
  47.     app = Application(args)
  48.     actions = tuple(Main.create_application_menubar())
  49.     app.setWindowIcon(QIcon(I('library.png')))
  50.     return (app, opts, args, actions)
  51.  
  52.  
  53. def get_default_library_path():
  54.     fname = _('Calibre Library')
  55.     if iswindows:
  56.         fname = 'Calibre Library'
  57.     
  58.     if isinstance(fname, unicode):
  59.         
  60.         try:
  61.             fname = fname.encode(filesystem_encoding)
  62.         fname = 'Calibre Library'
  63.  
  64.     
  65.     x = os.path.expanduser('~' + os.sep + fname)
  66.     if not os.path.exists(x):
  67.         
  68.         try:
  69.             os.makedirs(x)
  70.         x = os.path.expanduser('~')
  71.  
  72.     
  73.     return x
  74.  
  75.  
  76. def get_library_path(parent = None):
  77.     library_path = prefs['library_path']
  78.     if library_path is None:
  79.         base = os.path.expanduser('~')
  80.         if iswindows:
  81.             base = plugins['winutil'][0].special_folder_path(plugins['winutil'][0].CSIDL_PERSONAL)
  82.             if not base or not os.path.exists(base):
  83.                 QDir = QDir
  84.                 import PyQt4.Qt
  85.                 base = unicode(QDir.homePath()).replace('/', os.sep)
  86.             
  87.         
  88.         candidate = choose_dir(None, 'choose calibre library', _('Choose a location for your calibre e-book library'), default_dir = base)
  89.         if not candidate:
  90.             candidate = os.path.join(base, 'Calibre Library')
  91.         
  92.         library_path = os.path.abspath(candidate)
  93.     
  94.     if not os.path.exists(library_path):
  95.         
  96.         try:
  97.             os.makedirs(library_path)
  98.         error_dialog(parent, _('Failed to create library'), _('Failed to create calibre library at: %r.') % library_path, det_msg = traceback.format_exc(), show = True)
  99.         library_path = choose_dir(parent, 'choose calibre library', _('Choose a location for your new calibre e-book library'), default_dir = get_default_library_path())
  100.  
  101.     
  102.     return library_path
  103.  
  104.  
  105. class DBRepair(QThread):
  106.     repair_done = pyqtSignal(object, object)
  107.     progress = pyqtSignal(object, object)
  108.     
  109.     def __init__(self, library_path, parent, pd):
  110.         QThread.__init__(self, parent)
  111.         self.library_path = library_path
  112.         self.pd = pd
  113.         self.progress.connect(self._callback, type = Qt.QueuedConnection)
  114.  
  115.     
  116.     def _callback(self, num, is_length):
  117.         if is_length:
  118.             self.pd.setRange(0, num - 1)
  119.             num = 0
  120.         
  121.         self.pd.setValue(num)
  122.  
  123.     
  124.     def callback(self, num, is_length):
  125.         self.progress.emit(num, is_length)
  126.  
  127.     
  128.     def run(self):
  129.         reinit_db = reinit_db
  130.         import calibre.debug
  131.         
  132.         try:
  133.             reinit_db(os.path.join(self.library_path, 'metadata.db'), self.callback)
  134.             db = LibraryDatabase2(self.library_path)
  135.             tb = None
  136.         except:
  137.             db = None
  138.             tb = traceback.format_exc()
  139.  
  140.         self.repair_done.emit(db, tb)
  141.  
  142.  
  143.  
  144. class GuiRunner(QObject):
  145.     
  146.     def __init__(self, opts, args, actions, listener, app):
  147.         self.startup_time = time.time()
  148.         (self.opts, self.args, self.listener, self.app) = (opts, args, listener, app)
  149.         self.actions = actions
  150.         self.main = None
  151.         QObject.__init__(self)
  152.         self.splash_screen = None
  153.         self.timer = QTimer.singleShot(1, self.initialize)
  154.         if DEBUG:
  155.             prints('Starting up...')
  156.         
  157.  
  158.     
  159.     def start_gui(self):
  160.         Main = Main
  161.         import calibre.gui2.ui
  162.         main = Main(self.opts)
  163.         if self.splash_screen is not None:
  164.             self.splash_screen.showMessage(_('Initializing user interface...'))
  165.             self.splash_screen.finish(main)
  166.         
  167.         main.initialize(self.library_path, self.db, self.listener, self.actions)
  168.         if DEBUG:
  169.             prints('Started up in', time.time() - self.startup_time)
  170.         
  171.         add_filesystem_book = partial(main.add_filesystem_book, allow_device = False)
  172.         sys.excepthook = main.unhandled_exception
  173.         if len(self.args) > 1:
  174.             p = os.path.abspath(self.args[1])
  175.             add_filesystem_book(p)
  176.         
  177.         self.app.file_event_hook = add_filesystem_book
  178.         self.main = main
  179.  
  180.     
  181.     def initialization_failed(self):
  182.         print 'Catastrophic failure initializing GUI, bailing out...'
  183.         QCoreApplication.exit(1)
  184.         raise SystemExit(1)
  185.  
  186.     
  187.     def initialize_db_stage2(self, db, tb):
  188.         repair_pd = getattr(self, 'repair_pd', None)
  189.         if repair_pd is not None:
  190.             repair_pd.cancel()
  191.         
  192.         if db is None and tb is not None:
  193.             error_dialog(self.splash_screen, _('Repairing failed'), _('The database repair failed. Starting with a new empty library.'), det_msg = tb, show = True)
  194.         
  195.         if db is None:
  196.             candidate = choose_dir(self.splash_screen, 'choose calibre library', _('Choose a location for your new calibre e-book library'), default_dir = get_default_library_path())
  197.             if not candidate:
  198.                 self.initialization_failed()
  199.             
  200.             
  201.             try:
  202.                 self.library_path = candidate
  203.                 db = LibraryDatabase2(candidate)
  204.             error_dialog(self.splash_screen, _('Bad database location'), _('Bad database location %r. calibre will now quit.') % self.library_path, det_msg = traceback.format_exc(), show = True)
  205.             self.initialization_failed()
  206.  
  207.         
  208.         self.db = db
  209.         self.start_gui()
  210.  
  211.     
  212.     def initialize_db(self):
  213.         db = None
  214.         
  215.         try:
  216.             db = LibraryDatabase2(self.library_path)
  217.         except (sqlite.Error, DatabaseException):
  218.             repair = question_dialog(self.splash_screen, _('Corrupted database'), _('Your calibre database appears to be corrupted. Do you want calibre to try and repair it automatically? If you say No, a new empty calibre library will be created.'), det_msg = traceback.format_exc())
  219.             if repair:
  220.                 self.repair_pd = QProgressDialog(_('Repairing database. This can take a very long time for a large collection'), QString(), 0, 0)
  221.                 self.repair_pd.setWindowModality(Qt.WindowModal)
  222.                 self.repair_pd.show()
  223.                 self.repair = DBRepair(self.library_path, self, self.repair_pd)
  224.                 self.repair.repair_done.connect(self.initialize_db_stage2, type = Qt.QueuedConnection)
  225.                 self.repair.start()
  226.                 return None
  227.         except:
  228.             repair
  229.             error_dialog(self.splash_screen, _('Bad database location'), _('Bad database location %r. Will start with  a new, empty calibre library') % self.library_path, det_msg = traceback.format_exc(), show = True)
  230.  
  231.         self.initialize_db_stage2(db, None)
  232.  
  233.     
  234.     def show_splash_screen(self):
  235.         self.splash_pixmap = QPixmap()
  236.         self.splash_pixmap.load(I('library.png'))
  237.         self.splash_screen = QSplashScreen(self.splash_pixmap, Qt.SplashScreen)
  238.         self.splash_screen.showMessage(_('Starting %s: Loading books...') % __appname__)
  239.         self.splash_screen.show()
  240.         QApplication.instance().processEvents()
  241.  
  242.     
  243.     def initialize(self, *args):
  244.         if gprefs.get('show_splash_screen', True):
  245.             self.show_splash_screen()
  246.         
  247.         self.library_path = get_library_path(parent = self.splash_screen)
  248.         if not self.library_path:
  249.             self.initialization_failed()
  250.         
  251.         self.initialize_db()
  252.  
  253.  
  254.  
  255. def run_gui(opts, args, actions, listener, app):
  256.     initialize_file_icon_provider()
  257.     if not dynamic.get('welcome_wizard_was_run', False):
  258.         wizard = wizard
  259.         import calibre.gui2.wizard
  260.         wizard().exec_()
  261.         dynamic.set('welcome_wizard_was_run', True)
  262.     
  263.     runner = GuiRunner(opts, args, actions, listener, app)
  264.     ret = app.exec_()
  265.     if getattr(runner.main, 'run_wizard_b4_shutdown', False):
  266.         wizard = wizard
  267.         import calibre.gui2.wizard
  268.         wizard().exec_()
  269.     
  270.     if getattr(runner.main, 'restart_after_quit', False):
  271.         e = None if getattr(sys, 'frozen', False) else sys.argv[0]
  272.         print 'Restarting with:', e, sys.argv
  273.         if hasattr(sys, 'frameworks_dir'):
  274.             app = os.path.dirname(os.path.dirname(sys.frameworks_dir))
  275.             import subprocess
  276.             subprocess.Popen('sleep 3s; open ' + app, shell = True)
  277.         else:
  278.             os.execvp(e, sys.argv)
  279.     elif iswindows:
  280.         
  281.         try:
  282.             runner.main.system_tray_icon.hide()
  283.  
  284.     
  285.     return ret
  286.  
  287.  
  288. def cant_start(msg = _('If you are sure it is not running') + ', ', what = None):
  289.     d = QMessageBox(QMessageBox.Critical, _('Cannot Start ') + __appname__, '<p>' + _('%s is already running.') % __appname__ + '</p>', QMessageBox.Ok)
  290.     base = '<p>%s</p><p>%s %s'
  291.     where = __appname__ + ' ' + _('may be running in the system tray, in the') + ' '
  292.     if isosx:
  293.         where += _('upper right region of the screen.')
  294.     else:
  295.         where += _('lower right region of the screen.')
  296.     if what is None:
  297.         if iswindows:
  298.             what = _('try rebooting your computer.')
  299.         else:
  300.             what = _('try deleting the file') + ': ' + ADDRESS
  301.     
  302.     d.setInformativeText(base % (where, msg, what))
  303.     d.exec_()
  304.     raise SystemExit(1)
  305.  
  306.  
  307. def communicate(args):
  308.     t = RC()
  309.     t.start()
  310.     time.sleep(3)
  311.     if not t.done:
  312.         f = os.path.expanduser('~/.calibre_calibre GUI.lock')
  313.         cant_start(what = _('try deleting the file') + ': ' + f)
  314.         raise SystemExit(1)
  315.     t.done
  316.     if len(args) > 1:
  317.         args[1] = os.path.abspath(args[1])
  318.     
  319.     t.conn.send('launched:' + repr(args))
  320.     t.conn.close()
  321.     raise SystemExit(0)
  322.  
  323.  
  324. def main(args = sys.argv):
  325.     (app, opts, args, actions) = init_qt(args)
  326.     singleinstance = singleinstance
  327.     import calibre.utils.lock
  328.     Listener = Listener
  329.     import multiprocessing.connection
  330.     si = singleinstance('calibre GUI')
  331.     if si:
  332.         
  333.         try:
  334.             listener = Listener(address = ADDRESS)
  335.         except socket.error:
  336.             if iswindows:
  337.                 cant_start()
  338.             
  339.             os.remove(ADDRESS)
  340.             
  341.             try:
  342.                 listener = Listener(address = ADDRESS)
  343.             except socket.error:
  344.                 cant_start()
  345.  
  346.             return run_gui(opts, args, actions, listener, app)
  347.  
  348.         return run_gui(opts, args, actions, listener, app)
  349.     si
  350.     otherinstance = False
  351.     
  352.     try:
  353.         listener = Listener(address = ADDRESS)
  354.     except socket.error:
  355.         otherinstance = True
  356.  
  357.     otherinstance = None if iswindows else False
  358.     if not otherinstance:
  359.         return run_gui(opts, args, actions, listener, app)
  360.     communicate(args)
  361.     return 0
  362.  
  363. if __name__ == '__main__':
  364.     
  365.     try:
  366.         sys.exit(main())
  367.     except Exception:
  368.         err = None
  369.         if not iswindows:
  370.             raise 
  371.         iswindows
  372.         tb = traceback.format_exc()
  373.         from PyQt4.QtGui import QErrorMessage
  374.         logfile = os.path.join(os.path.expanduser('~'), 'calibre.log')
  375.         if os.path.exists(logfile):
  376.             log = open(logfile).read().decode('utf-8', 'ignore')
  377.             d = QErrorMessage()
  378.             d.showMessage('<b>Error:</b>%s<br><b>Traceback:</b><br>%s<b>Log:</b><br>%s' % (unicode(err), unicode(tb).replace('\n', '<br>'), log.replace('\n', '<br>')))
  379.         
  380.     except:
  381.         os.path.exists(logfile)
  382.     
  383.  
  384. None<EXCEPTION MATCH>Exception
  385.