home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 January / maximum-cd-2011-01.iso / DiscContents / calibre-0.7.26.msi / file_1165 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-10-31  |  13.2 KB  |  324 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __license__ = 'GPL v3'
  5. __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
  6. __docformat__ = 'restructuredtext en'
  7. import os
  8. from functools import partial
  9. from PyQt4.Qt import Qt, QMenu
  10. from calibre.gui2 import error_dialog, config
  11. from calibre.gui2.dialogs.metadata_single import MetadataSingleDialog
  12. from calibre.gui2.dialogs.metadata_bulk import MetadataBulkDialog
  13. from calibre.gui2.dialogs.confirm_delete import confirm
  14. from calibre.gui2.dialogs.tag_list_editor import TagListEditor
  15. from calibre.gui2.actions import InterfaceAction
  16.  
  17. class EditMetadataAction(InterfaceAction):
  18.     name = 'Edit Metadata'
  19.     action_spec = (_('Edit metadata'), 'edit_input.png', None, _('E'))
  20.     action_type = 'current'
  21.     
  22.     def genesis(self):
  23.         self.create_action(spec = (_('Merge book records'), 'merge_books.png', None, _('M')), attr = 'action_merge')
  24.         md = QMenu()
  25.         md.addAction(_('Edit metadata individually'), partial(self.edit_metadata, False, bulk = False))
  26.         md.addSeparator()
  27.         md.addAction(_('Edit metadata in bulk'), partial(self.edit_metadata, False, bulk = True))
  28.         md.addSeparator()
  29.         md.addAction(_('Download metadata and covers'), partial(self.download_metadata, False, covers = True), Qt.ControlModifier + Qt.Key_D)
  30.         md.addAction(_('Download only metadata'), partial(self.download_metadata, False, covers = False))
  31.         md.addAction(_('Download only covers'), partial(self.download_metadata, False, covers = True, set_metadata = False, set_social_metadata = False))
  32.         md.addAction(_('Download only social metadata'), partial(self.download_metadata, False, covers = False, set_metadata = False, set_social_metadata = True))
  33.         self.metadata_menu = md
  34.         mb = QMenu()
  35.         mb.addAction(_('Merge into first selected book - delete others'), self.merge_books)
  36.         mb.addSeparator()
  37.         mb.addAction(_('Merge into first selected book - keep others'), partial(self.merge_books, safe_merge = True), Qt.AltModifier + Qt.Key_M)
  38.         self.merge_menu = mb
  39.         self.action_merge.setMenu(mb)
  40.         md.addSeparator()
  41.         md.addAction(self.action_merge)
  42.         self.qaction.triggered.connect(self.edit_metadata)
  43.         self.qaction.setMenu(md)
  44.         self.action_merge.triggered.connect(self.merge_books)
  45.  
  46.     
  47.     def location_selected(self, loc):
  48.         enabled = loc == 'library'
  49.         self.qaction.setEnabled(enabled)
  50.         self.action_merge.setEnabled(enabled)
  51.  
  52.     
  53.     def download_metadata(self, checked, covers = True, set_metadata = True, set_social_metadata = None):
  54.         rows = self.gui.library_view.selectionModel().selectedRows()
  55.         if not rows or len(rows) == 0:
  56.             d = error_dialog(self.gui, _('Cannot download metadata'), _('No books selected'))
  57.             d.exec_()
  58.             return None
  59.         db = self.gui.library_view.model().db
  60.         ids = [ db.id(row.row()) for row in rows ]
  61.         self.do_download_metadata(ids, covers = covers, set_metadata = set_metadata, set_social_metadata = set_social_metadata)
  62.  
  63.     
  64.     def do_download_metadata(self, ids, covers = True, set_metadata = True, set_social_metadata = None):
  65.         m = self.gui.library_view.model()
  66.         db = m.db
  67.         if set_social_metadata is None:
  68.             get_social_metadata = config['get_social_metadata']
  69.         else:
  70.             get_social_metadata = set_social_metadata
  71.         DoDownload = DoDownload
  72.         import calibre.gui2.metadata
  73.         if set_social_metadata is not None and set_social_metadata:
  74.             x = _('social metadata')
  75.         elif covers and not set_metadata:
  76.             pass
  77.         
  78.         x = _('metadata')
  79.         title = _('Downloading %s for %d book(s)') % (x, len(ids))
  80.         self._download_book_metadata = DoDownload(self.gui, title, db, ids, get_covers = covers, set_metadata = set_metadata, get_social_metadata = get_social_metadata)
  81.         m.stop_metadata_backup()
  82.         
  83.         try:
  84.             self._download_book_metadata.exec_()
  85.         finally:
  86.             m.start_metadata_backup()
  87.  
  88.         cr = self.gui.library_view.currentIndex().row()
  89.         x = self._download_book_metadata
  90.         if x.updated:
  91.             self.gui.library_view.model().refresh_ids(x.updated, cr)
  92.             if self.gui.cover_flow:
  93.                 self.gui.cover_flow.dataChanged()
  94.             
  95.         
  96.  
  97.     
  98.     def edit_metadata(self, checked, bulk = None):
  99.         rows = self.gui.library_view.selectionModel().selectedRows()
  100.         previous = self.gui.library_view.currentIndex()
  101.         if not rows or len(rows) == 0:
  102.             d = error_dialog(self.gui, _('Cannot edit metadata'), _('No books selected'))
  103.             d.exec_()
  104.             return None
  105.         if (bulk or bulk is None) and len(rows) > 1:
  106.             return self.edit_bulk_metadata(checked)
  107.         
  108.         def accepted(id):
  109.             self.gui.library_view.model().refresh_ids([
  110.                 id])
  111.  
  112.         for row in rows:
  113.             self.gui.iactions['View'].metadata_view_id = self.gui.library_view.model().db.id(row.row())
  114.             d = MetadataSingleDialog(self.gui, row.row(), self.gui.library_view.model().db, accepted_callback = accepted, cancel_all = rows.index(row) < len(rows) - 1)
  115.             d.view_format.connect(self.gui.iactions['View'].metadata_view_format)
  116.             d.exec_()
  117.             if d.cancel_all:
  118.                 break
  119.                 continue
  120.             (len(rows) > 1,)
  121.         
  122.  
  123.     
  124.     def edit_bulk_metadata(self, checked):
  125.         rows = [ r.row() for r in self.gui.library_view.selectionModel().selectedRows() ]
  126.         m = self.gui.library_view.model()
  127.         ids = [ m.id(r) for r in rows ]
  128.         if not rows or len(rows) == 0:
  129.             d = error_dialog(self.gui, _('Cannot edit metadata'), _('No books selected'))
  130.             d.exec_()
  131.             return None
  132.         self.gui.tags_view.blockSignals(True)
  133.         
  134.         try:
  135.             changed = MetadataBulkDialog(self.gui, rows, self.gui.library_view.model()).changed
  136.         finally:
  137.             self.gui.tags_view.blockSignals(False)
  138.  
  139.  
  140.     
  141.     def merge_books(self, safe_merge = False):
  142.         if self.gui.stack.currentIndex() != 0:
  143.             return None
  144.         rows = self.gui.library_view.selectionModel().selectedRows()
  145.         if not rows or len(rows) == 0:
  146.             return error_dialog(self.gui, _('Cannot merge books'), _('No books selected'), show = True)
  147.         if len(rows) < 2:
  148.             return error_dialog(self.gui, _('Cannot merge books'), _('At least two books must be selected for merging'), show = True)
  149.         (dest_id, src_books, src_ids) = self.books_to_merge(rows)
  150.         if safe_merge:
  151.             if not confirm('<p>' + _('Book formats and metadata from the selected books will be added to the <b>first selected book.</b> ISBN will <i>not</i> be merged.<br><br> The second and subsequently selected books will not be deleted or changed.<br><br>Please confirm you want to proceed.') + '</p>', 'merge_books_safe', self.gui):
  152.                 return None
  153.             self.add_formats(dest_id, src_books)
  154.             self.merge_metadata(dest_id, src_ids)
  155.         elif not confirm('<p>' + _('Book formats and metadata from the selected books will be merged into the <b>first selected book</b>. ISBN will <i>not</i> be merged.<br><br>After merger the second and subsequently selected books will be <b>deleted</b>. <br><br>All book formats of the first selected book will be kept and any duplicate formats in the second and subsequently selected books will be permanently <b>deleted</b> from your computer.<br><br>  Are you <b>sure</b> you want to proceed?') + '</p>', 'merge_books', self.gui):
  156.             return None
  157.         len(rows) < 2
  158.         self.add_formats(dest_id, src_books)
  159.         self.merge_metadata(dest_id, src_ids)
  160.         self.delete_books_after_merge(src_ids)
  161.         dest_row = rows[0].row()
  162.         for row in rows:
  163.             if row.row() < rows[0].row():
  164.                 dest_row -= 1
  165.                 continue
  166.             self.gui.stack.currentIndex() != 0 if len(rows) > 5 else len(rows) == 0
  167.         
  168.         ci = self.gui.library_view.model().index(dest_row, 0)
  169.         if ci.isValid():
  170.             self.gui.library_view.setCurrentIndex(ci)
  171.         
  172.  
  173.     
  174.     def add_formats(self, dest_id, src_books, replace = False):
  175.         for src_book in src_books:
  176.             if src_book:
  177.                 fmt = os.path.splitext(src_book)[-1].replace('.', '').upper()
  178.                 
  179.                 try:
  180.                     f = _[1]
  181.                     self.gui.library_view.model().db.add_format(dest_id, fmt, f, index_is_id = True, notify = False, replace = replace)
  182.                 finally:
  183.                     pass
  184.  
  185.                 continue
  186.             open(src_book, 'rb').__exit__
  187.         
  188.  
  189.     
  190.     def books_to_merge(self, rows):
  191.         src_books = []
  192.         src_ids = []
  193.         m = self.gui.library_view.model()
  194.         for i, row in enumerate(rows):
  195.             id_ = m.id(row)
  196.             if i == 0:
  197.                 dest_id = id_
  198.                 continue
  199.             src_ids.append(id_)
  200.             dbfmts = m.db.formats(id_, index_is_id = True)
  201.             if dbfmts:
  202.                 for fmt in dbfmts.split(','):
  203.                     src_books.append(m.db.format_abspath(id_, fmt, index_is_id = True))
  204.                 
  205.         
  206.         return [
  207.             dest_id,
  208.             src_books,
  209.             src_ids]
  210.  
  211.     
  212.     def delete_books_after_merge(self, ids_to_delete):
  213.         self.gui.library_view.model().delete_books_by_id(ids_to_delete)
  214.  
  215.     
  216.     def merge_metadata(self, dest_id, src_ids):
  217.         db = self.gui.library_view.model().db
  218.         dest_mi = db.get_metadata(dest_id, index_is_id = True, get_cover = True)
  219.         orig_dest_comments = dest_mi.comments
  220.         for src_id in src_ids:
  221.             src_mi = db.get_metadata(src_id, index_is_id = True, get_cover = True)
  222.             if src_mi.comments and orig_dest_comments != src_mi.comments:
  223.                 if not dest_mi.comments:
  224.                     dest_mi.comments = src_mi.comments
  225.                 else:
  226.                     dest_mi.comments = unicode(dest_mi.comments) + u'\n\n' + unicode(src_mi.comments)
  227.             
  228.             if src_mi.title:
  229.                 if not (dest_mi.title) or dest_mi.title == _('Unknown'):
  230.                     dest_mi.title = src_mi.title
  231.                 
  232.             if src_mi.title:
  233.                 if not (dest_mi.authors) or dest_mi.authors[0] == _('Unknown'):
  234.                     dest_mi.authors = src_mi.authors
  235.                     dest_mi.author_sort = src_mi.author_sort
  236.                 
  237.             if src_mi.tags:
  238.                 if not dest_mi.tags:
  239.                     dest_mi.tags = src_mi.tags
  240.                 else:
  241.                     dest_mi.tags.extend(src_mi.tags)
  242.             
  243.             if src_mi.cover and not (dest_mi.cover):
  244.                 dest_mi.cover = src_mi.cover
  245.             
  246.             if not dest_mi.publisher:
  247.                 dest_mi.publisher = src_mi.publisher
  248.             
  249.             if not dest_mi.rating:
  250.                 dest_mi.rating = src_mi.rating
  251.             
  252.             if not dest_mi.series:
  253.                 dest_mi.series = src_mi.series
  254.                 dest_mi.series_index = src_mi.series_index
  255.                 continue
  256.         
  257.         db.set_metadata(dest_id, dest_mi, ignore_errors = False)
  258.         for key in db.field_metadata:
  259.             if db.field_metadata[key]['is_custom']:
  260.                 colnum = db.field_metadata[key]['colnum']
  261.                 if db.field_metadata[key]['datatype'] == 'comments':
  262.                     orig_dest_value = db.get_custom(dest_id, num = colnum, index_is_id = True)
  263.                 
  264.                 for src_id in src_ids:
  265.                     dest_value = db.get_custom(dest_id, num = colnum, index_is_id = True)
  266.                     src_value = db.get_custom(src_id, num = colnum, index_is_id = True)
  267.                     if db.field_metadata[key]['datatype'] == 'comments':
  268.                         if src_value and src_value != orig_dest_value:
  269.                             if not dest_value:
  270.                                 db.set_custom(dest_id, src_value, num = colnum)
  271.                             else:
  272.                                 dest_value = unicode(dest_value) + u'\n\n' + unicode(src_value)
  273.                                 db.set_custom(dest_id, dest_value, num = colnum)
  274.                         
  275.                     
  276.                     if db.field_metadata[key]['datatype'] in ('bool', 'int', 'float', 'rating', 'datetime') and not dest_value:
  277.                         db.set_custom(dest_id, src_value, num = colnum)
  278.                     
  279.                     if db.field_metadata[key]['datatype'] == 'series' and not dest_value:
  280.                         if src_value:
  281.                             src_index = db.get_custom_extra(src_id, num = colnum, index_is_id = True)
  282.                             db.set_custom(dest_id, src_value, num = colnum, extra = src_index)
  283.                         
  284.                     
  285.                     if db.field_metadata[key]['datatype'] == 'text' and not db.field_metadata[key]['is_multiple'] and not dest_value:
  286.                         db.set_custom(dest_id, src_value, num = colnum)
  287.                     
  288.                     if db.field_metadata[key]['datatype'] == 'text' and db.field_metadata[key]['is_multiple']:
  289.                         if src_value:
  290.                             if not dest_value:
  291.                                 dest_value = src_value
  292.                             else:
  293.                                 dest_value.extend(src_value)
  294.                             db.set_custom(dest_id, dest_value, num = colnum)
  295.                         
  296.                     src_value
  297.                 
  298.         
  299.  
  300.     
  301.     def edit_device_collections(self, view, oncard = None):
  302.         model = view.model()
  303.         result = model.get_collections_with_ids()
  304.         
  305.         compare = lambda x, y: cmp(x.lower(), y.lower())
  306.         d = TagListEditor(self.gui, tag_to_match = None, data = result, compare = compare)
  307.         d.exec_()
  308.         if d.result() == d.Accepted:
  309.             to_rename = d.to_rename
  310.             to_delete = d.to_delete
  311.             for text in to_rename:
  312.                 for old_id in to_rename[text]:
  313.                     model.rename_collection(old_id, new_name = unicode(text))
  314.                 
  315.             
  316.             for item in to_delete:
  317.                 model.delete_collection_using_id(item)
  318.             
  319.             self.gui.upload_collections(model.db, view = view, oncard = oncard)
  320.             view.reset()
  321.         
  322.  
  323.  
  324.