mirror of
				https://github.com/kovidgoyal/calibre.git
				synced 2025-11-04 03:27:00 -05:00 
			
		
		
		
	GwR resolve conflicts after merge with KG latest
This commit is contained in:
		
						commit
						03a83560a4
					
				
							
								
								
									
										
											BIN
										
									
								
								icons/book.icns
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								icons/book.icns
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 11 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/images/news/michellemalkin_icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								resources/images/news/michellemalkin_icon.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 419 B  | 
							
								
								
									
										49
									
								
								resources/recipes/michellemalkin.recipe
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								resources/recipes/michellemalkin.recipe
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
				
			|||||||
 | 
					__license__   = 'GPL v3'
 | 
				
			||||||
 | 
					__copyright__ = '2010, Walt Anthony <workshop.northpole at gmail.com>'
 | 
				
			||||||
 | 
					'''
 | 
				
			||||||
 | 
					www.michellemalkin.com
 | 
				
			||||||
 | 
					'''
 | 
				
			||||||
 | 
					from calibre.web.feeds.news import BasicNewsRecipe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MichelleMalkin(BasicNewsRecipe):
 | 
				
			||||||
 | 
					    title          = u'Michelle Malkin'
 | 
				
			||||||
 | 
					    description    = "Michelle Malkin's take on events, a mother, wife, blogger, conservative syndicated columnist, author, and Fox News Channel contributor."
 | 
				
			||||||
 | 
					    __author__     = 'Walt Anthony'
 | 
				
			||||||
 | 
					    publisher             = 'Michelle Malkin LLC'
 | 
				
			||||||
 | 
					    category              = 'news, politics, USA'
 | 
				
			||||||
 | 
					    oldest_article        = 7 #days
 | 
				
			||||||
 | 
					    max_articles_per_feed = 50
 | 
				
			||||||
 | 
					    summary_length        = 150
 | 
				
			||||||
 | 
					    language              = 'en'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    remove_javascript     = True
 | 
				
			||||||
 | 
					    no_stylesheets        = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    conversion_options = {
 | 
				
			||||||
 | 
					                          'comment'   : description
 | 
				
			||||||
 | 
					                        , 'tags'      : category
 | 
				
			||||||
 | 
					                        , 'publisher' : publisher
 | 
				
			||||||
 | 
					                        , 'language'  : language
 | 
				
			||||||
 | 
					                        , 'linearize_tables' : True
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    keep_only_tags = [
 | 
				
			||||||
 | 
					      dict(name='div', attrs={'class':'article'})
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    remove_tags  = [
 | 
				
			||||||
 | 
					       dict(name=['iframe', 'embed', 'object']),
 | 
				
			||||||
 | 
					       dict(name='div', attrs={'id':['comments', 'commentForm']}),
 | 
				
			||||||
 | 
					       dict(name='div', attrs={'class':['postCategories', 'comments', 'blogInfo', 'postInfo']})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    feeds = [(u'http://feeds.feedburner.com/michellemalkin/posts')]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def print_version(self, url):
 | 
				
			||||||
 | 
					        return url + '?print=1'
 | 
				
			||||||
							
								
								
									
										22
									
								
								resources/recipes/open_left.recipe
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								resources/recipes/open_left.recipe
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					from calibre.web.feeds.news import BasicNewsRecipe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class OpenLeft(BasicNewsRecipe):
 | 
				
			||||||
 | 
					    # Information about the recipe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    title              = 'Open Left'
 | 
				
			||||||
 | 
					    description        = 'Progressive American commentary on current events'
 | 
				
			||||||
 | 
					    category           = 'news, commentary'
 | 
				
			||||||
 | 
					    language           = 'en'
 | 
				
			||||||
 | 
					    __author__         = 'Xanthan Gum'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Fetch no article older than seven days
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    oldest_article = 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Fetch no more than 100 articles
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    max_articles_per_feed = 100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Fetch the articles from the RSS feed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    feeds          = [(u'Articles', u'http://www.openleft.com/rss/rss2.xml')]
 | 
				
			||||||
@ -266,6 +266,7 @@ class Py2App(object):
 | 
				
			|||||||
    def get_local_dependencies(self, path_to_lib):
 | 
					    def get_local_dependencies(self, path_to_lib):
 | 
				
			||||||
        for x in self.get_dependencies(path_to_lib):
 | 
					        for x in self.get_dependencies(path_to_lib):
 | 
				
			||||||
            for y in (SW+'/lib/', '/usr/local/lib/', SW+'/qt/lib/',
 | 
					            for y in (SW+'/lib/', '/usr/local/lib/', SW+'/qt/lib/',
 | 
				
			||||||
 | 
					                    '/opt/local/lib/',
 | 
				
			||||||
                    '/Library/Frameworks/Python.framework/', SW+'/freetype/lib/'):
 | 
					                    '/Library/Frameworks/Python.framework/', SW+'/freetype/lib/'):
 | 
				
			||||||
                if x.startswith(y):
 | 
					                if x.startswith(y):
 | 
				
			||||||
                    if y == '/Library/Frameworks/Python.framework/':
 | 
					                    if y == '/Library/Frameworks/Python.framework/':
 | 
				
			||||||
@ -338,7 +339,7 @@ class Py2App(object):
 | 
				
			|||||||
        c = join(self.build_dir, 'Contents')
 | 
					        c = join(self.build_dir, 'Contents')
 | 
				
			||||||
        for x in ('Frameworks', 'MacOS', 'Resources'):
 | 
					        for x in ('Frameworks', 'MacOS', 'Resources'):
 | 
				
			||||||
            os.makedirs(join(c, x))
 | 
					            os.makedirs(join(c, x))
 | 
				
			||||||
        x = 'library.icns'
 | 
					        for x in ('library.icns', 'book.icns'):
 | 
				
			||||||
            shutil.copyfile(join('icons', x), join(self.resources_dir, x))
 | 
					            shutil.copyfile(join('icons', x), join(self.resources_dir, x))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @flush
 | 
					    @flush
 | 
				
			||||||
@ -355,8 +356,13 @@ class Py2App(object):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @flush
 | 
					    @flush
 | 
				
			||||||
    def create_plist(self):
 | 
					    def create_plist(self):
 | 
				
			||||||
 | 
					        from calibre.ebooks import BOOK_EXTENSIONS
 | 
				
			||||||
        env = dict(**ENV)
 | 
					        env = dict(**ENV)
 | 
				
			||||||
        env['CALIBRE_LAUNCHED_FROM_BUNDLE']='1';
 | 
					        env['CALIBRE_LAUNCHED_FROM_BUNDLE']='1';
 | 
				
			||||||
 | 
					        docs = [{'CFBundleTypeName':'E-book',
 | 
				
			||||||
 | 
					            'CFBundleTypeExtensions':list(BOOK_EXTENSIONS),
 | 
				
			||||||
 | 
					            'CFBundleTypeRole':'Viewer',
 | 
				
			||||||
 | 
					            }]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        pl = dict(
 | 
					        pl = dict(
 | 
				
			||||||
                CFBundleDevelopmentRegion='English',
 | 
					                CFBundleDevelopmentRegion='English',
 | 
				
			||||||
@ -367,10 +373,11 @@ class Py2App(object):
 | 
				
			|||||||
                CFBundlePackageType='APPL',
 | 
					                CFBundlePackageType='APPL',
 | 
				
			||||||
                CFBundleSignature='????',
 | 
					                CFBundleSignature='????',
 | 
				
			||||||
                CFBundleExecutable='calibre',
 | 
					                CFBundleExecutable='calibre',
 | 
				
			||||||
 | 
					                CFBundleDocumentTypes=docs,
 | 
				
			||||||
                LSMinimumSystemVersion='10.4.2',
 | 
					                LSMinimumSystemVersion='10.4.2',
 | 
				
			||||||
                LSRequiresNativeExecution=True,
 | 
					                LSRequiresNativeExecution=True,
 | 
				
			||||||
                NSAppleScriptEnabled=False,
 | 
					                NSAppleScriptEnabled=False,
 | 
				
			||||||
                NSHumanReadableCopyright='Copyright 2008, Kovid Goyal',
 | 
					                NSHumanReadableCopyright='Copyright 2010, Kovid Goyal',
 | 
				
			||||||
                CFBundleGetInfoString=('calibre, an E-book management '
 | 
					                CFBundleGetInfoString=('calibre, an E-book management '
 | 
				
			||||||
                'application. Visit http://calibre-ebook.com for details.'),
 | 
					                'application. Visit http://calibre-ebook.com for details.'),
 | 
				
			||||||
                CFBundleIconFile='library.icns',
 | 
					                CFBundleIconFile='library.icns',
 | 
				
			||||||
@ -594,6 +601,7 @@ class Py2App(object):
 | 
				
			|||||||
            if x == 'Info.plist':
 | 
					            if x == 'Info.plist':
 | 
				
			||||||
                plist = plistlib.readPlist(join(self.contents_dir, x))
 | 
					                plist = plistlib.readPlist(join(self.contents_dir, x))
 | 
				
			||||||
                plist['LSUIElement'] = '1'
 | 
					                plist['LSUIElement'] = '1'
 | 
				
			||||||
 | 
					                plist.pop('CFBundleDocumentTypes')
 | 
				
			||||||
                plistlib.writePlist(plist, join(cc_dir, x))
 | 
					                plistlib.writePlist(plist, join(cc_dir, x))
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                os.symlink(join('../..', x),
 | 
					                os.symlink(join('../..', x),
 | 
				
			||||||
 | 
				
			|||||||
@ -274,7 +274,7 @@ class BookList(_BookList):
 | 
				
			|||||||
            node.setAttribute(attr, attrs[attr])
 | 
					            node.setAttribute(attr, attrs[attr])
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            w, h, data = mi.thumbnail
 | 
					            w, h, data = mi.thumbnail
 | 
				
			||||||
        except TypeError:
 | 
					        except:
 | 
				
			||||||
            w, h, data = None, None, None
 | 
					            w, h, data = None, None, None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if data:
 | 
					        if data:
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@ __docformat__ = 'restructuredtext en'
 | 
				
			|||||||
Based on ideas from comiclrf created by FangornUK.
 | 
					Based on ideas from comiclrf created by FangornUK.
 | 
				
			||||||
'''
 | 
					'''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import os, shutil, traceback, textwrap, time
 | 
					import os, shutil, traceback, textwrap, time, codecs
 | 
				
			||||||
from ctypes import byref
 | 
					from ctypes import byref
 | 
				
			||||||
from Queue import Empty
 | 
					from Queue import Empty
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -338,8 +338,9 @@ class ComicInput(InputFormatPlugin):
 | 
				
			|||||||
            if not os.path.exists('comics.txt'):
 | 
					            if not os.path.exists('comics.txt'):
 | 
				
			||||||
                raise ValueError('%s is not a valid comic collection'
 | 
					                raise ValueError('%s is not a valid comic collection'
 | 
				
			||||||
                        %stream.name)
 | 
					                        %stream.name)
 | 
				
			||||||
            for line in open('comics.txt',
 | 
					            raw = open('comics.txt', 'rb').read().decode('utf-8')
 | 
				
			||||||
                    'rb').read().decode('utf-8').splitlines():
 | 
					            raw.lstrip(unicode(codecs.BOM_UTF8, "utf8" ))
 | 
				
			||||||
 | 
					            for line in raw.splitlines():
 | 
				
			||||||
                line = line.strip()
 | 
					                line = line.strip()
 | 
				
			||||||
                if not line:
 | 
					                if not line:
 | 
				
			||||||
                    continue
 | 
					                    continue
 | 
				
			||||||
 | 
				
			|||||||
@ -269,7 +269,7 @@ class EPUBOutput(OutputFormatPlugin):
 | 
				
			|||||||
                bad = []
 | 
					                bad = []
 | 
				
			||||||
                for x in XPath('//h:img')(body):
 | 
					                for x in XPath('//h:img')(body):
 | 
				
			||||||
                    src = x.get('src', '').strip()
 | 
					                    src = x.get('src', '').strip()
 | 
				
			||||||
                    if src in ('', '#'):
 | 
					                    if src in ('', '#') or src.startswith('http:'):
 | 
				
			||||||
                        bad.append(x)
 | 
					                        bad.append(x)
 | 
				
			||||||
                for img in bad:
 | 
					                for img in bad:
 | 
				
			||||||
                    img.getparent().remove(img)
 | 
					                    img.getparent().remove(img)
 | 
				
			||||||
 | 
				
			|||||||
@ -573,6 +573,8 @@ class MobiReader(object):
 | 
				
			|||||||
                                attrib[attr] = "%dpx"%int(nval)
 | 
					                                attrib[attr] = "%dpx"%int(nval)
 | 
				
			||||||
                            except:
 | 
					                            except:
 | 
				
			||||||
                                del attrib[attr]
 | 
					                                del attrib[attr]
 | 
				
			||||||
 | 
					                        elif val.lower().endswith('%'):
 | 
				
			||||||
 | 
					                            del attrib[attr]
 | 
				
			||||||
            elif tag.tag == 'pre':
 | 
					            elif tag.tag == 'pre':
 | 
				
			||||||
                if not tag.text:
 | 
					                if not tag.text:
 | 
				
			||||||
                    tag.tag = 'div'
 | 
					                    tag.tag = 'div'
 | 
				
			||||||
 | 
				
			|||||||
@ -3,7 +3,8 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
 | 
				
			|||||||
""" The GUI """
 | 
					""" The GUI """
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
from PyQt4.QtCore import QVariant, QFileInfo, QObject, SIGNAL, QBuffer, Qt, QSize, \
 | 
					from PyQt4.QtCore import QVariant, QFileInfo, QObject, SIGNAL, QBuffer, Qt, QSize, \
 | 
				
			||||||
                         QByteArray, QTranslator, QCoreApplication, QThread
 | 
					                         QByteArray, QTranslator, QCoreApplication, QThread, \
 | 
				
			||||||
 | 
					                         QEvent
 | 
				
			||||||
from PyQt4.QtGui import QFileDialog, QMessageBox, QPixmap, QFileIconProvider, \
 | 
					from PyQt4.QtGui import QFileDialog, QMessageBox, QPixmap, QFileIconProvider, \
 | 
				
			||||||
                        QIcon, QTableView, QApplication, QDialog, QPushButton
 | 
					                        QIcon, QTableView, QApplication, QDialog, QPushButton
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -524,6 +525,7 @@ class Application(QApplication):
 | 
				
			|||||||
    def __init__(self, args):
 | 
					    def __init__(self, args):
 | 
				
			||||||
        qargs = [i.encode('utf-8') if isinstance(i, unicode) else i for i in args]
 | 
					        qargs = [i.encode('utf-8') if isinstance(i, unicode) else i for i in args]
 | 
				
			||||||
        QApplication.__init__(self, qargs)
 | 
					        QApplication.__init__(self, qargs)
 | 
				
			||||||
 | 
					        self.file_event_hook = None
 | 
				
			||||||
        global gui_thread, qt_app
 | 
					        global gui_thread, qt_app
 | 
				
			||||||
        gui_thread = QThread.currentThread()
 | 
					        gui_thread = QThread.currentThread()
 | 
				
			||||||
        self._translator = None
 | 
					        self._translator = None
 | 
				
			||||||
@ -549,6 +551,15 @@ class Application(QApplication):
 | 
				
			|||||||
        if set_qt_translator(self._translator):
 | 
					        if set_qt_translator(self._translator):
 | 
				
			||||||
            self.installTranslator(self._translator)
 | 
					            self.installTranslator(self._translator)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def event(self, e):
 | 
				
			||||||
 | 
					        if callable(self.file_event_hook) and e.type() == QEvent.FileOpen:
 | 
				
			||||||
 | 
					            path = unicode(e.file())
 | 
				
			||||||
 | 
					            if os.access(path, os.R_OK):
 | 
				
			||||||
 | 
					                self.file_event_hook(path)
 | 
				
			||||||
 | 
					            return True
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return QApplication.event(self, e)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_store_app = None
 | 
					_store_app = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def is_ok_to_use_qt():
 | 
					def is_ok_to_use_qt():
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,7 @@ from calibre.gui2.dialogs.progress import ProgressDialog
 | 
				
			|||||||
from calibre.gui2 import question_dialog, error_dialog, info_dialog
 | 
					from calibre.gui2 import question_dialog, error_dialog, info_dialog
 | 
				
			||||||
from calibre.ebooks.metadata.opf2 import OPF
 | 
					from calibre.ebooks.metadata.opf2 import OPF
 | 
				
			||||||
from calibre.ebooks.metadata import MetaInformation
 | 
					from calibre.ebooks.metadata import MetaInformation
 | 
				
			||||||
from calibre.constants import preferred_encoding
 | 
					from calibre.constants import preferred_encoding, filesystem_encoding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DuplicatesAdder(QThread):
 | 
					class DuplicatesAdder(QThread):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -46,6 +46,8 @@ class RecursiveFind(QThread):
 | 
				
			|||||||
    def run(self):
 | 
					    def run(self):
 | 
				
			||||||
        root = os.path.abspath(self.path)
 | 
					        root = os.path.abspath(self.path)
 | 
				
			||||||
        self.books = []
 | 
					        self.books = []
 | 
				
			||||||
 | 
					        if isinstance(root, unicode):
 | 
				
			||||||
 | 
					            root = root.encode(filesystem_encoding)
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            for dirpath in os.walk(root):
 | 
					            for dirpath in os.walk(root):
 | 
				
			||||||
                if self.canceled:
 | 
					                if self.canceled:
 | 
				
			||||||
@ -55,6 +57,8 @@ class RecursiveFind(QThread):
 | 
				
			|||||||
                self.books += list(self.db.find_books_in_directory(dirpath[0],
 | 
					                self.books += list(self.db.find_books_in_directory(dirpath[0],
 | 
				
			||||||
                                                self.single_book_per_directory))
 | 
					                                                self.single_book_per_directory))
 | 
				
			||||||
        except Exception, err:
 | 
					        except Exception, err:
 | 
				
			||||||
 | 
					            import traceback
 | 
				
			||||||
 | 
					            traceback.print_exc()
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                msg = unicode(err)
 | 
					                msg = unicode(err)
 | 
				
			||||||
            except:
 | 
					            except:
 | 
				
			||||||
 | 
				
			|||||||
@ -20,10 +20,8 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog):
 | 
				
			|||||||
        self.db = db
 | 
					        self.db = db
 | 
				
			||||||
        self.ids = [ db.id(r) for r in rows]
 | 
					        self.ids = [ db.id(r) for r in rows]
 | 
				
			||||||
        self.write_series = False
 | 
					        self.write_series = False
 | 
				
			||||||
        self.write_rating = False
 | 
					 | 
				
			||||||
        self.changed = False
 | 
					        self.changed = False
 | 
				
			||||||
        QObject.connect(self.button_box, SIGNAL("accepted()"), self.sync)
 | 
					        QObject.connect(self.button_box, SIGNAL("accepted()"), self.sync)
 | 
				
			||||||
        QObject.connect(self.rating, SIGNAL('valueChanged(int)'), self.rating_changed)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.tags.update_tags_cache(self.db.all_tags())
 | 
					        self.tags.update_tags_cache(self.db.all_tags())
 | 
				
			||||||
        self.remove_tags.update_tags_cache(self.db.all_tags())
 | 
					        self.remove_tags.update_tags_cache(self.db.all_tags())
 | 
				
			||||||
@ -99,7 +97,7 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog):
 | 
				
			|||||||
            aus = unicode(self.author_sort.text())
 | 
					            aus = unicode(self.author_sort.text())
 | 
				
			||||||
            if aus and self.author_sort.isEnabled():
 | 
					            if aus and self.author_sort.isEnabled():
 | 
				
			||||||
                self.db.set_author_sort(id, aus, notify=False)
 | 
					                self.db.set_author_sort(id, aus, notify=False)
 | 
				
			||||||
            if self.write_rating:
 | 
					            if self.rating.value() != -1:
 | 
				
			||||||
                self.db.set_rating(id, 2*self.rating.value(), notify=False)
 | 
					                self.db.set_rating(id, 2*self.rating.value(), notify=False)
 | 
				
			||||||
            pub = unicode(self.publisher.text())
 | 
					            pub = unicode(self.publisher.text())
 | 
				
			||||||
            if pub:
 | 
					            if pub:
 | 
				
			||||||
@ -134,5 +132,3 @@ class MetadataBulkDialog(QDialog, Ui_MetadataBulkDialog):
 | 
				
			|||||||
    def series_changed(self):
 | 
					    def series_changed(self):
 | 
				
			||||||
        self.write_series = True
 | 
					        self.write_series = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def rating_changed(self):
 | 
					 | 
				
			||||||
        self.write_rating = True
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -96,12 +96,21 @@
 | 
				
			|||||||
          <property name="buttonSymbols">
 | 
					          <property name="buttonSymbols">
 | 
				
			||||||
           <enum>QAbstractSpinBox::PlusMinus</enum>
 | 
					           <enum>QAbstractSpinBox::PlusMinus</enum>
 | 
				
			||||||
          </property>
 | 
					          </property>
 | 
				
			||||||
 | 
					          <property name="specialValueText">
 | 
				
			||||||
 | 
					           <string>No change</string>
 | 
				
			||||||
 | 
					          </property>
 | 
				
			||||||
          <property name="suffix">
 | 
					          <property name="suffix">
 | 
				
			||||||
           <string> stars</string>
 | 
					           <string> stars</string>
 | 
				
			||||||
          </property>
 | 
					          </property>
 | 
				
			||||||
 | 
					          <property name="minimum">
 | 
				
			||||||
 | 
					           <number>-1</number>
 | 
				
			||||||
 | 
					          </property>
 | 
				
			||||||
          <property name="maximum">
 | 
					          <property name="maximum">
 | 
				
			||||||
           <number>5</number>
 | 
					           <number>5</number>
 | 
				
			||||||
          </property>
 | 
					          </property>
 | 
				
			||||||
 | 
					          <property name="value">
 | 
				
			||||||
 | 
					           <number>-1</number>
 | 
				
			||||||
 | 
					          </property>
 | 
				
			||||||
         </widget>
 | 
					         </widget>
 | 
				
			||||||
        </item>
 | 
					        </item>
 | 
				
			||||||
        <item row="4" column="0">
 | 
					        <item row="4" column="0">
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@ __license__   = 'GPL v3'
 | 
				
			|||||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
 | 
					__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import sys, os, time, socket, traceback
 | 
					import sys, os, time, socket, traceback
 | 
				
			||||||
 | 
					from functools import partial
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from PyQt4.Qt import QCoreApplication, QIcon, QMessageBox
 | 
					from PyQt4.Qt import QCoreApplication, QIcon, QMessageBox
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -52,10 +53,12 @@ def run_gui(opts, args, actions, listener, app):
 | 
				
			|||||||
        wizard().exec_()
 | 
					        wizard().exec_()
 | 
				
			||||||
        dynamic.set('welcome_wizard_was_run', True)
 | 
					        dynamic.set('welcome_wizard_was_run', True)
 | 
				
			||||||
    main = Main(listener, opts, actions)
 | 
					    main = Main(listener, opts, actions)
 | 
				
			||||||
 | 
					    add_filesystem_book = partial(main.add_filesystem_book, allow_device=False)
 | 
				
			||||||
    sys.excepthook = main.unhandled_exception
 | 
					    sys.excepthook = main.unhandled_exception
 | 
				
			||||||
    if len(args) > 1:
 | 
					    if len(args) > 1:
 | 
				
			||||||
        args[1] = os.path.abspath(args[1])
 | 
					        args[1] = os.path.abspath(args[1])
 | 
				
			||||||
        main.add_filesystem_book(args[1])
 | 
					        add_filesystem_book(args[1])
 | 
				
			||||||
 | 
					    app.file_event_hook = add_filesystem_book
 | 
				
			||||||
    ret = app.exec_()
 | 
					    ret = app.exec_()
 | 
				
			||||||
    if getattr(main, 'run_wizard_b4_shutdown', False):
 | 
					    if getattr(main, 'run_wizard_b4_shutdown', False):
 | 
				
			||||||
        from calibre.gui2.wizard import wizard
 | 
					        from calibre.gui2.wizard import wizard
 | 
				
			||||||
 | 
				
			|||||||
@ -987,10 +987,10 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
 | 
				
			|||||||
            self.cover_cache.refresh([cid])
 | 
					            self.cover_cache.refresh([cid])
 | 
				
			||||||
            self.library_view.model().current_changed(current_idx, current_idx)
 | 
					            self.library_view.model().current_changed(current_idx, current_idx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def add_filesystem_book(self, path):
 | 
					    def add_filesystem_book(self, path, allow_device=True):
 | 
				
			||||||
        if os.access(path, os.R_OK):
 | 
					        if os.access(path, os.R_OK):
 | 
				
			||||||
            books = [os.path.abspath(path)]
 | 
					            books = [os.path.abspath(path)]
 | 
				
			||||||
            to_device = self.stack.currentIndex() != 0
 | 
					            to_device = allow_device and self.stack.currentIndex() != 0
 | 
				
			||||||
            self._add_books(books, to_device)
 | 
					            self._add_books(books, to_device)
 | 
				
			||||||
            if to_device:
 | 
					            if to_device:
 | 
				
			||||||
                self.status_bar.showMessage(\
 | 
					                self.status_bar.showMessage(\
 | 
				
			||||||
@ -1048,6 +1048,8 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
 | 
				
			|||||||
        if self._adder.critical:
 | 
					        if self._adder.critical:
 | 
				
			||||||
            det_msg = []
 | 
					            det_msg = []
 | 
				
			||||||
            for name, log in self._adder.critical.items():
 | 
					            for name, log in self._adder.critical.items():
 | 
				
			||||||
 | 
					                if isinstance(name, str):
 | 
				
			||||||
 | 
					                    name = name.decode(filesystem_encoding, 'replace')
 | 
				
			||||||
                det_msg.append(name+'\n'+log)
 | 
					                det_msg.append(name+'\n'+log)
 | 
				
			||||||
            warning_dialog(self, _('Failed to read metadata'),
 | 
					            warning_dialog(self, _('Failed to read metadata'),
 | 
				
			||||||
                    _('Failed to read metadata from the following')+':',
 | 
					                    _('Failed to read metadata from the following')+':',
 | 
				
			||||||
 | 
				
			|||||||
@ -514,7 +514,7 @@ class DocumentView(QWebView):
 | 
				
			|||||||
            mt = guess_type(path)[0]
 | 
					            mt = guess_type(path)[0]
 | 
				
			||||||
        html = open(path, 'rb').read().decode(path.encoding, 'replace')
 | 
					        html = open(path, 'rb').read().decode(path.encoding, 'replace')
 | 
				
			||||||
        html = EntityDeclarationProcessor(html).processed_html
 | 
					        html = EntityDeclarationProcessor(html).processed_html
 | 
				
			||||||
        has_svg = re.search(r'<[:a-z]*svg', html) is not None
 | 
					        has_svg = re.search(r'<[:a-zA-Z]*svg', html) is not None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if 'xhtml' in mt:
 | 
					        if 'xhtml' in mt:
 | 
				
			||||||
            html = self.self_closing_pat.sub(self.self_closing_sub, html)
 | 
					            html = self.self_closing_pat.sub(self.self_closing_sub, html)
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@ from collections import namedtuple
 | 
				
			|||||||
from datetime import date
 | 
					from datetime import date
 | 
				
			||||||
from xml.sax.saxutils import escape
 | 
					from xml.sax.saxutils import escape
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from calibre import filesystem_encoding, prints
 | 
					from calibre import filesystem_encoding, prints, strftime
 | 
				
			||||||
from calibre.customize import CatalogPlugin
 | 
					from calibre.customize import CatalogPlugin
 | 
				
			||||||
from calibre.customize.conversion import OptionRecommendation, DummyReporter
 | 
					from calibre.customize.conversion import OptionRecommendation, DummyReporter
 | 
				
			||||||
from calibre.ebooks.BeautifulSoup import BeautifulSoup, BeautifulStoneSoup, Tag, NavigableString
 | 
					from calibre.ebooks.BeautifulSoup import BeautifulSoup, BeautifulStoneSoup, Tag, NavigableString
 | 
				
			||||||
@ -97,7 +97,7 @@ class CSV_XML(CatalogPlugin):
 | 
				
			|||||||
                        item = ', '.join(item)
 | 
					                        item = ', '.join(item)
 | 
				
			||||||
                    elif field == 'isbn':
 | 
					                    elif field == 'isbn':
 | 
				
			||||||
                        # Could be 9, 10 or 13 digits
 | 
					                        # Could be 9, 10 or 13 digits
 | 
				
			||||||
                        field = '%s' % re.sub('[\D]','',field)
 | 
					                        field = u'%s' % re.sub(r'[\D]','',field)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if x < len(fields) - 1:
 | 
					                    if x < len(fields) - 1:
 | 
				
			||||||
                        if item is not None:
 | 
					                        if item is not None:
 | 
				
			||||||
@ -488,9 +488,6 @@ class EPUB_MOBI(CatalogPlugin):
 | 
				
			|||||||
        current_step = 0.0
 | 
					        current_step = 0.0
 | 
				
			||||||
        total_steps = 14.0
 | 
					        total_steps = 14.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Used to xlate pubdate to friendly format
 | 
					 | 
				
			||||||
        MONTHS = ['','January', 'February','March','April','May','June',
 | 
					 | 
				
			||||||
                      'July','August','September','October','November','December']
 | 
					 | 
				
			||||||
        THUMB_WIDTH = 75
 | 
					        THUMB_WIDTH = 75
 | 
				
			||||||
        THUMB_HEIGHT = 100
 | 
					        THUMB_HEIGHT = 100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -878,9 +875,7 @@ class EPUB_MOBI(CatalogPlugin):
 | 
				
			|||||||
                    this_title['publisher'] = re.sub('&', '&', record['publisher'])
 | 
					                    this_title['publisher'] = re.sub('&', '&', record['publisher'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                this_title['rating'] = record['rating'] if record['rating'] else 0
 | 
					                this_title['rating'] = record['rating'] if record['rating'] else 0
 | 
				
			||||||
                # <pubdate>2009-11-05 09:29:37</pubdate>
 | 
					                this_title['date'] = strftime(u'%b %Y', record['pubdate'].timetuple())
 | 
				
			||||||
                date_strings = str(record['pubdate']).split("-")
 | 
					 | 
				
			||||||
                this_title['date'] = '%s %s' % (self.MONTHS[int(date_strings[1])], date_strings[0])
 | 
					 | 
				
			||||||
                this_title['timestamp'] = record['timestamp']
 | 
					                this_title['timestamp'] = record['timestamp']
 | 
				
			||||||
                if record['comments']:
 | 
					                if record['comments']:
 | 
				
			||||||
                    this_title['description'] = re.sub('&', '&', record['comments'])
 | 
					                    this_title['description'] = re.sub('&', '&', record['comments'])
 | 
				
			||||||
@ -1332,11 +1327,11 @@ class EPUB_MOBI(CatalogPlugin):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            def add_books_to_HTML(this_months_list, dtc):
 | 
					            def add_books_to_HTML(this_months_list, dtc):
 | 
				
			||||||
                if len(this_months_list):
 | 
					                if len(this_months_list):
 | 
				
			||||||
 | 
					                    date_string = strftime(u'%b %Y', current_date.timetuple())
 | 
				
			||||||
                    this_months_list = sorted(this_months_list,
 | 
					                    this_months_list = sorted(this_months_list,
 | 
				
			||||||
                                        key=lambda x:(x['title_sort'], x['title_sort']))
 | 
					                                        key=lambda x:(x['title_sort'], x['title_sort']))
 | 
				
			||||||
                    this_months_list = sorted(this_months_list,
 | 
					                    this_months_list = sorted(this_months_list,
 | 
				
			||||||
                                        key=lambda x:(x['author_sort'], x['author_sort']))
 | 
					                                        key=lambda x:(x['author_sort'], x['author_sort']))
 | 
				
			||||||
 | 
					 | 
				
			||||||
                    # Create a new month anchor
 | 
					                    # Create a new month anchor
 | 
				
			||||||
                    pIndexTag = Tag(soup, "p")
 | 
					                    pIndexTag = Tag(soup, "p")
 | 
				
			||||||
                    pIndexTag['class'] = "date_index"
 | 
					                    pIndexTag['class'] = "date_index"
 | 
				
			||||||
@ -1435,7 +1430,6 @@ class EPUB_MOBI(CatalogPlugin):
 | 
				
			|||||||
            dtc = 0
 | 
					            dtc = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            current_date = date.fromordinal(1)
 | 
					            current_date = date.fromordinal(1)
 | 
				
			||||||
            current_author = None
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Loop through books by date
 | 
					            # Loop through books by date
 | 
				
			||||||
            this_months_list = []
 | 
					            this_months_list = []
 | 
				
			||||||
@ -2066,7 +2060,6 @@ class EPUB_MOBI(CatalogPlugin):
 | 
				
			|||||||
            # add description_preview_count titles
 | 
					            # add description_preview_count titles
 | 
				
			||||||
            # self.authors[0]:friendly [1]:author_sort [2]:book_count
 | 
					            # self.authors[0]:friendly [1]:author_sort [2]:book_count
 | 
				
			||||||
            current_titles_list = []
 | 
					            current_titles_list = []
 | 
				
			||||||
            current_author_list = []
 | 
					 | 
				
			||||||
            master_month_list = []
 | 
					            master_month_list = []
 | 
				
			||||||
            current_date = self.booksByDate[0]['timestamp']
 | 
					            current_date = self.booksByDate[0]['timestamp']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2088,6 +2081,7 @@ class EPUB_MOBI(CatalogPlugin):
 | 
				
			|||||||
            # Add *article* entries for each populated month
 | 
					            # Add *article* entries for each populated month
 | 
				
			||||||
            # master_months_list{}: [0]:titles list [1]:date
 | 
					            # master_months_list{}: [0]:titles list [1]:date
 | 
				
			||||||
            for books_by_month in master_month_list:
 | 
					            for books_by_month in master_month_list:
 | 
				
			||||||
 | 
					                datestr = strftime(u'%b %Y', books_by_month[1].timetuple())
 | 
				
			||||||
                navPointByMonthTag = Tag(soup, 'navPoint')
 | 
					                navPointByMonthTag = Tag(soup, 'navPoint')
 | 
				
			||||||
                navPointByMonthTag['class'] = "article"
 | 
					                navPointByMonthTag['class'] = "article"
 | 
				
			||||||
                navPointByMonthTag['id'] = "%s-%s-ID" % (books_by_month[1].year,books_by_month[1].month )
 | 
					                navPointByMonthTag['id'] = "%s-%s-ID" % (books_by_month[1].year,books_by_month[1].month )
 | 
				
			||||||
@ -2095,8 +2089,7 @@ class EPUB_MOBI(CatalogPlugin):
 | 
				
			|||||||
                self.playOrder += 1
 | 
					                self.playOrder += 1
 | 
				
			||||||
                navLabelTag = Tag(soup, 'navLabel')
 | 
					                navLabelTag = Tag(soup, 'navLabel')
 | 
				
			||||||
                textTag = Tag(soup, 'text')
 | 
					                textTag = Tag(soup, 'text')
 | 
				
			||||||
                textTag.insert(0, NavigableString("Books added in %s %s" % \
 | 
					                textTag.insert(0, NavigableString("Books added in " + datestr))
 | 
				
			||||||
                    (self.MONTHS[books_by_month[1].month], books_by_month[1].year)))
 | 
					 | 
				
			||||||
                navLabelTag.insert(0, textTag)
 | 
					                navLabelTag.insert(0, textTag)
 | 
				
			||||||
                navPointByMonthTag.insert(0,navLabelTag)
 | 
					                navPointByMonthTag.insert(0,navLabelTag)
 | 
				
			||||||
                contentTag = Tag(soup, 'content')
 | 
					                contentTag = Tag(soup, 'content')
 | 
				
			||||||
 | 
				
			|||||||
@ -84,6 +84,7 @@ if not _run_once:
 | 
				
			|||||||
        return res
 | 
					        return res
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    os.path.abspath = my_abspath
 | 
					    os.path.abspath = my_abspath
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _join = os.path.join
 | 
					    _join = os.path.join
 | 
				
			||||||
    def my_join(a, *p):
 | 
					    def my_join(a, *p):
 | 
				
			||||||
        encoding=sys.getfilesystemencoding()
 | 
					        encoding=sys.getfilesystemencoding()
 | 
				
			||||||
 | 
				
			|||||||
@ -558,8 +558,6 @@ class BasicNewsRecipe(Recipe):
 | 
				
			|||||||
            '--max-recursions', str(self.recursions),
 | 
					            '--max-recursions', str(self.recursions),
 | 
				
			||||||
            '--delay', str(self.delay),
 | 
					            '--delay', str(self.delay),
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
        if self.encoding is not None:
 | 
					 | 
				
			||||||
            web2disk_cmdline.extend(['--encoding', self.encoding])
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.verbose:
 | 
					        if self.verbose:
 | 
				
			||||||
            web2disk_cmdline.append('--verbose')
 | 
					            web2disk_cmdline.append('--verbose')
 | 
				
			||||||
@ -578,6 +576,7 @@ class BasicNewsRecipe(Recipe):
 | 
				
			|||||||
                      'preprocess_html', 'remove_tags_after', 'remove_tags_before'):
 | 
					                      'preprocess_html', 'remove_tags_after', 'remove_tags_before'):
 | 
				
			||||||
            setattr(self.web2disk_options, extra, getattr(self, extra))
 | 
					            setattr(self.web2disk_options, extra, getattr(self, extra))
 | 
				
			||||||
        self.web2disk_options.postprocess_html = self._postprocess_html
 | 
					        self.web2disk_options.postprocess_html = self._postprocess_html
 | 
				
			||||||
 | 
					        self.web2disk_options.encoding = self.encoding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.delay > 0:
 | 
					        if self.delay > 0:
 | 
				
			||||||
            self.simultaneous_downloads = 1
 | 
					            self.simultaneous_downloads = 1
 | 
				
			||||||
@ -761,6 +760,7 @@ class BasicNewsRecipe(Recipe):
 | 
				
			|||||||
        self.report_progress(0, _('Trying to download cover...'))
 | 
					        self.report_progress(0, _('Trying to download cover...'))
 | 
				
			||||||
        self.download_cover()
 | 
					        self.download_cover()
 | 
				
			||||||
        self.report_progress(0, _('Generating masthead...'))
 | 
					        self.report_progress(0, _('Generating masthead...'))
 | 
				
			||||||
 | 
					        self.masthead_path = None
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            murl = self.get_masthead_url()
 | 
					            murl = self.get_masthead_url()
 | 
				
			||||||
        except:
 | 
					        except:
 | 
				
			||||||
@ -768,7 +768,7 @@ class BasicNewsRecipe(Recipe):
 | 
				
			|||||||
            murl = None
 | 
					            murl = None
 | 
				
			||||||
        if murl is not None:
 | 
					        if murl is not None:
 | 
				
			||||||
            self.download_masthead(murl)
 | 
					            self.download_masthead(murl)
 | 
				
			||||||
        else:
 | 
					        if self.masthead_path is None:
 | 
				
			||||||
            self.masthead_path = os.path.join(self.output_dir, 'mastheadImage.jpg')
 | 
					            self.masthead_path = os.path.join(self.output_dir, 'mastheadImage.jpg')
 | 
				
			||||||
            self.default_masthead_image(self.masthead_path)
 | 
					            self.default_masthead_image(self.masthead_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -894,7 +894,7 @@ class BasicNewsRecipe(Recipe):
 | 
				
			|||||||
            ext = ''
 | 
					            ext = ''
 | 
				
			||||||
        ext = ext.lower() if ext else 'jpg'
 | 
					        ext = ext.lower() if ext else 'jpg'
 | 
				
			||||||
        mpath = os.path.join(self.output_dir, 'masthead_source.'+ext)
 | 
					        mpath = os.path.join(self.output_dir, 'masthead_source.'+ext)
 | 
				
			||||||
        self.masthead_path = os.path.join(self.output_dir, 'mastheadImage.jpg')
 | 
					        outfile = os.path.join(self.output_dir, 'mastheadImage.jpg')
 | 
				
			||||||
        if os.access(mu, os.R_OK):
 | 
					        if os.access(mu, os.R_OK):
 | 
				
			||||||
            with open(mpath, 'wb') as mfile:
 | 
					            with open(mpath, 'wb') as mfile:
 | 
				
			||||||
                mfile.write(open(mu, 'rb').read())
 | 
					                mfile.write(open(mu, 'rb').read())
 | 
				
			||||||
@ -902,20 +902,17 @@ class BasicNewsRecipe(Recipe):
 | 
				
			|||||||
            with nested(open(mpath, 'wb'), closing(self.browser.open(mu))) as (mfile, r):
 | 
					            with nested(open(mpath, 'wb'), closing(self.browser.open(mu))) as (mfile, r):
 | 
				
			||||||
                mfile.write(r.read())
 | 
					                mfile.write(r.read())
 | 
				
			||||||
            self.report_progress(1, _('Masthead image downloaded'))
 | 
					            self.report_progress(1, _('Masthead image downloaded'))
 | 
				
			||||||
        self.prepare_masthead_image(mpath, self.masthead_path)
 | 
					        self.prepare_masthead_image(mpath, outfile)
 | 
				
			||||||
 | 
					        self.masthead_path = outfile
 | 
				
			||||||
        if os.path.exists(mpath):
 | 
					        if os.path.exists(mpath):
 | 
				
			||||||
            os.remove(mpath)
 | 
					            os.remove(mpath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def download_masthead(self, url):
 | 
					    def download_masthead(self, url):
 | 
				
			||||||
        br = BasicNewsRecipe.get_browser()
 | 
					 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            br.open(url)
 | 
					 | 
				
			||||||
            self._download_masthead(url)
 | 
					            self._download_masthead(url)
 | 
				
			||||||
        except:
 | 
					        except:
 | 
				
			||||||
            self.log.exception("Failed to download supplied masthead_url, synthesizing")
 | 
					            self.log.exception("Failed to download supplied masthead_url, synthesizing")
 | 
				
			||||||
            self.masthead_path = os.path.join(self.output_dir, 'mastheadImage.jpg')
 | 
					 | 
				
			||||||
            self.default_masthead_image(self.masthead_path)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def default_cover(self, cover_file):
 | 
					    def default_cover(self, cover_file):
 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user