mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Merge from main branch
This commit is contained in:
commit
716e38b20e
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>'
|
__copyright__ = '2010, Darko Miletic <darko.miletic at gmail.com>'
|
||||||
'''
|
'''
|
||||||
@ -19,11 +18,11 @@ class SueddeutcheZeitung(BasicNewsRecipe):
|
|||||||
encoding = 'cp1252'
|
encoding = 'cp1252'
|
||||||
needs_subscription = True
|
needs_subscription = True
|
||||||
remove_empty_feeds = True
|
remove_empty_feeds = True
|
||||||
delay = 2
|
delay = 1
|
||||||
PREFIX = 'http://www.sueddeutsche.de'
|
PREFIX = 'http://www.sueddeutsche.de'
|
||||||
INDEX = PREFIX + '/app/epaper/textversion/'
|
INDEX = PREFIX + '/app/epaper/textversion/'
|
||||||
use_embedded_content = False
|
use_embedded_content = False
|
||||||
masthead_url = 'http://pix.sueddeutsche.de/img/layout/header/logo.gif'
|
masthead_url = 'http://pix.sueddeutsche.de/img/layout/header/SZ_solo288x31.gif'
|
||||||
language = 'de'
|
language = 'de'
|
||||||
publication_type = 'newspaper'
|
publication_type = 'newspaper'
|
||||||
extra_css = ' body{font-family: Arial,Helvetica,sans-serif} '
|
extra_css = ' body{font-family: Arial,Helvetica,sans-serif} '
|
||||||
@ -36,7 +35,7 @@ class SueddeutcheZeitung(BasicNewsRecipe):
|
|||||||
, 'linearize_tables' : True
|
, 'linearize_tables' : True
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_attributes = ['height','width']
|
remove_attributes = ['height','width','style']
|
||||||
|
|
||||||
def get_browser(self):
|
def get_browser(self):
|
||||||
br = BasicNewsRecipe.get_browser()
|
br = BasicNewsRecipe.get_browser()
|
||||||
@ -50,24 +49,37 @@ class SueddeutcheZeitung(BasicNewsRecipe):
|
|||||||
|
|
||||||
remove_tags =[
|
remove_tags =[
|
||||||
dict(attrs={'class':'hidePrint'})
|
dict(attrs={'class':'hidePrint'})
|
||||||
,dict(name=['link','object','embed','base','iframe'])
|
,dict(name=['link','object','embed','base','iframe','br'])
|
||||||
]
|
]
|
||||||
keep_only_tags = [dict(attrs={'class':'artikelBox'})]
|
keep_only_tags = [dict(attrs={'class':'artikelBox'})]
|
||||||
remove_tags_before = dict(attrs={'class':'artikelTitel'})
|
remove_tags_before = dict(attrs={'class':'artikelTitel'})
|
||||||
remove_tags_after = dict(attrs={'class':'author'})
|
remove_tags_after = dict(attrs={'class':'author'})
|
||||||
|
|
||||||
feeds = [
|
feeds = [
|
||||||
(u'Politik' , INDEX + 'Politik/' )
|
(u'Politik' , INDEX + 'Politik/' )
|
||||||
,(u'Seite drei' , INDEX + 'Seite+drei/' )
|
,(u'Seite drei' , INDEX + 'Seite+drei/' )
|
||||||
,(u'Meinungsseite', INDEX + 'Meinungsseite/')
|
,(u'Meinungsseite' , INDEX + 'Meinungsseite/')
|
||||||
,(u'Wissen' , INDEX + 'Wissen/' )
|
,(u'Wissen' , INDEX + 'Wissen/' )
|
||||||
,(u'Panorama' , INDEX + 'Panorama/' )
|
,(u'Panorama' , INDEX + 'Panorama/' )
|
||||||
,(u'Feuilleton' , INDEX + 'Feuilleton/' )
|
,(u'Feuilleton' , INDEX + 'Feuilleton/' )
|
||||||
,(u'Medien' , INDEX + 'Medien/' )
|
,(u'Medien' , INDEX + 'Medien/' )
|
||||||
,(u'Wirtschaft' , INDEX + 'Wirtschaft/' )
|
,(u'Wirtschaft' , INDEX + 'Wirtschaft/' )
|
||||||
,(u'Sport' , INDEX + 'Sport/' )
|
,(u'Sport' , INDEX + 'Sport/' )
|
||||||
,(u'Bayern' , INDEX + 'Bayern/' )
|
,(u'Bayern' , INDEX + 'Bayern/' )
|
||||||
,(u'Muenchen' , INDEX + 'M%FCnchen/' )
|
,(u'Muenchen' , INDEX + 'M%FCnchen/' )
|
||||||
|
,(u'Muenchen City' , INDEX + 'M%FCnchen+City/' )
|
||||||
|
,(u'Jetzt.de' , INDEX + 'Jetzt.de/' )
|
||||||
|
,(u'Reise' , INDEX + 'Reise/' )
|
||||||
|
,(u'SZ Extra' , INDEX + 'SZ+Extra/' )
|
||||||
|
,(u'Wochenende' , INDEX + 'SZ+am+Wochenende/' )
|
||||||
|
,(u'Stellen-Markt' , INDEX + 'Stellen-Markt/')
|
||||||
|
,(u'Motormarkt' , INDEX + 'Motormarkt/')
|
||||||
|
,(u'Immobilien-Markt', INDEX + 'Immobilien-Markt/')
|
||||||
|
,(u'Thema' , INDEX + 'Thema/' )
|
||||||
|
,(u'Forum' , INDEX + 'Forum/' )
|
||||||
|
,(u'Leute' , INDEX + 'Leute/' )
|
||||||
|
,(u'Jugend' , INDEX + 'Jugend/' )
|
||||||
|
,(u'Beilage' , INDEX + 'Beilage/' )
|
||||||
]
|
]
|
||||||
|
|
||||||
def parse_index(self):
|
def parse_index(self):
|
||||||
|
@ -108,7 +108,7 @@ class ANDROID(USBMS):
|
|||||||
'SGH-T849', '_MB300', 'A70S', 'S_ANDROID', 'A101IT', 'A70H',
|
'SGH-T849', '_MB300', 'A70S', 'S_ANDROID', 'A101IT', 'A70H',
|
||||||
'IDEOS_TABLET', 'MYTOUCH_4G', 'UMS_COMPOSITE', 'SCH-I800_CARD',
|
'IDEOS_TABLET', 'MYTOUCH_4G', 'UMS_COMPOSITE', 'SCH-I800_CARD',
|
||||||
'7', 'A956', 'A955', 'A43', 'ANDROID_PLATFORM', 'TEGRA_2',
|
'7', 'A956', 'A955', 'A43', 'ANDROID_PLATFORM', 'TEGRA_2',
|
||||||
'MB860', 'MULTI-CARD']
|
'MB860', 'MULTI-CARD', 'MID7015A']
|
||||||
WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897',
|
WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897',
|
||||||
'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD',
|
'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD',
|
||||||
'A70S', 'A101IT', '7']
|
'A70S', 'A101IT', '7']
|
||||||
|
@ -141,7 +141,7 @@ class EXTHRecord(object):
|
|||||||
204 : 'Creator Software',
|
204 : 'Creator Software',
|
||||||
205 : 'Creator Major Version', # '>I'
|
205 : 'Creator Major Version', # '>I'
|
||||||
206 : 'Creator Minor Version', # '>I'
|
206 : 'Creator Minor Version', # '>I'
|
||||||
207 : 'Creator Build number', # '>I'
|
207 : 'Creator Build Number', # '>I'
|
||||||
208 : 'watermark',
|
208 : 'watermark',
|
||||||
209 : 'tamper_proof_keys',
|
209 : 'tamper_proof_keys',
|
||||||
300 : 'fontsignature',
|
300 : 'fontsignature',
|
||||||
@ -153,6 +153,11 @@ class EXTHRecord(object):
|
|||||||
503 : 'updatedtitle',
|
503 : 'updatedtitle',
|
||||||
}.get(self.type, repr(self.type))
|
}.get(self.type, repr(self.type))
|
||||||
|
|
||||||
|
if self.name in ('coveroffset', 'thumboffset', 'hasfakecover',
|
||||||
|
'Creator Major Version', 'Creator Minor Version',
|
||||||
|
'Creator Build Number', 'Creator Software', 'startreading'):
|
||||||
|
self.data, = struct.unpack(b'>I', self.data)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '%s (%d): %r'%(self.name, self.type, self.data)
|
return '%s (%d): %r'%(self.name, self.type, self.data)
|
||||||
|
|
||||||
@ -235,7 +240,9 @@ class MOBIHeader(object):
|
|||||||
}.get(self.encoding_raw, repr(self.encoding_raw))
|
}.get(self.encoding_raw, repr(self.encoding_raw))
|
||||||
self.uid = self.raw[32:36]
|
self.uid = self.raw[32:36]
|
||||||
self.file_version = struct.unpack(b'>I', self.raw[36:40])
|
self.file_version = struct.unpack(b'>I', self.raw[36:40])
|
||||||
self.reserved = self.raw[40:80]
|
self.reserved = self.raw[40:48]
|
||||||
|
self.secondary_index_record, = struct.unpack(b'>I', self.raw[48:52])
|
||||||
|
self.reserved2 = self.raw[52:80]
|
||||||
self.first_non_book_record, = struct.unpack(b'>I', self.raw[80:84])
|
self.first_non_book_record, = struct.unpack(b'>I', self.raw[80:84])
|
||||||
self.fullname_offset, = struct.unpack(b'>I', self.raw[84:88])
|
self.fullname_offset, = struct.unpack(b'>I', self.raw[84:88])
|
||||||
self.fullname_length, = struct.unpack(b'>I', self.raw[88:92])
|
self.fullname_length, = struct.unpack(b'>I', self.raw[88:92])
|
||||||
@ -255,18 +262,28 @@ class MOBIHeader(object):
|
|||||||
self.unknown2 = self.raw[120:128]
|
self.unknown2 = self.raw[120:128]
|
||||||
self.exth_flags, = struct.unpack(b'>I', self.raw[128:132])
|
self.exth_flags, = struct.unpack(b'>I', self.raw[128:132])
|
||||||
self.has_exth = bool(self.exth_flags & 0x40)
|
self.has_exth = bool(self.exth_flags & 0x40)
|
||||||
self.has_drm_data = self.length >= 184 and len(self.raw) >= 184
|
self.has_drm_data = self.length >= 174 and len(self.raw) >= 180
|
||||||
if self.has_drm_data:
|
if self.has_drm_data:
|
||||||
self.unknown3 = self.raw[132:164]
|
self.unknown3 = self.raw[132:164]
|
||||||
self.drm_offset, = struct.unpack(b'>I', self.raw[164:168])
|
self.drm_offset, = struct.unpack(b'>I', self.raw[164:168])
|
||||||
self.drm_count, = struct.unpack(b'>I', self.raw[168:172])
|
self.drm_count, = struct.unpack(b'>I', self.raw[168:172])
|
||||||
self.drm_size, = struct.unpack(b'>I', self.raw[172:176])
|
self.drm_size, = struct.unpack(b'>I', self.raw[172:176])
|
||||||
self.drm_flags = bin(struct.unpack(b'>I', self.raw[176:180])[0])
|
self.drm_flags = bin(struct.unpack(b'>I', self.raw[176:180])[0])
|
||||||
self.has_extra_data_flags = self.length >= 244 and len(self.raw) >= 244
|
self.has_extra_data_flags = self.length >= 232 and len(self.raw) >= 232+16
|
||||||
|
self.has_fcis_flis = False
|
||||||
if self.has_extra_data_flags:
|
if self.has_extra_data_flags:
|
||||||
self.unknown4 = self.raw[180:242]
|
self.unknown4 = self.raw[180:192]
|
||||||
self.extra_data_flags = bin(struct.unpack(b'>H',
|
self.first_content_record, self.last_content_record = \
|
||||||
self.raw[242:244])[0])
|
struct.unpack(b'>HH', self.raw[192:196])
|
||||||
|
self.unknown5, = struct.unpack(b'>I', self.raw[196:200])
|
||||||
|
(self.fcis_number, self.fcis_count, self.flis_number,
|
||||||
|
self.flis_count) = struct.unpack(b'>IIII',
|
||||||
|
self.raw[200:216])
|
||||||
|
self.unknown6 = self.raw[216:240]
|
||||||
|
self.extra_data_flags = bin(struct.unpack(b'>I',
|
||||||
|
self.raw[240:244])[0])
|
||||||
|
self.primary_index_record, = struct.unpack(b'>I',
|
||||||
|
self.raw[244:248])
|
||||||
|
|
||||||
if self.has_exth:
|
if self.has_exth:
|
||||||
self.exth_offset = 16 + self.length
|
self.exth_offset = 16 + self.length
|
||||||
@ -291,6 +308,9 @@ class MOBIHeader(object):
|
|||||||
ans.append('UID: %r'%self.uid)
|
ans.append('UID: %r'%self.uid)
|
||||||
ans.append('File version: %d'%self.file_version)
|
ans.append('File version: %d'%self.file_version)
|
||||||
ans.append('Reserved: %r'%self.reserved)
|
ans.append('Reserved: %r'%self.reserved)
|
||||||
|
ans.append('Secondary index record: %d (null val: %d)'%(
|
||||||
|
self.secondary_index_record, 0xffffffff))
|
||||||
|
ans.append('Reserved2: %r'%self.reserved2)
|
||||||
ans.append('First non-book record: %d'% self.first_non_book_record)
|
ans.append('First non-book record: %d'% self.first_non_book_record)
|
||||||
ans.append('Full name offset: %d'%self.fullname_offset)
|
ans.append('Full name offset: %d'%self.fullname_offset)
|
||||||
ans.append('Full name length: %d bytes'%self.fullname_length)
|
ans.append('Full name length: %d bytes'%self.fullname_length)
|
||||||
@ -313,7 +333,16 @@ class MOBIHeader(object):
|
|||||||
ans.append('DRM Flags: %r'%self.drm_flags)
|
ans.append('DRM Flags: %r'%self.drm_flags)
|
||||||
if self.has_extra_data_flags:
|
if self.has_extra_data_flags:
|
||||||
ans.append('Unknown4: %r'%self.unknown4)
|
ans.append('Unknown4: %r'%self.unknown4)
|
||||||
|
ans.append('First content record: %d'% self.first_content_record)
|
||||||
|
ans.append('Last content record: %d'% self.last_content_record)
|
||||||
|
ans.append('Unknown5: %d'% self.unknown5)
|
||||||
|
ans.append('FCIS number: %d'% self.fcis_number)
|
||||||
|
ans.append('FCIS count: %d'% self.fcis_count)
|
||||||
|
ans.append('FLIS number: %d'% self.flis_number)
|
||||||
|
ans.append('FLIS count: %d'% self.flis_count)
|
||||||
|
ans.append('Unknown6: %r'% self.unknown6)
|
||||||
ans.append('Extra data flags: %r'%self.extra_data_flags)
|
ans.append('Extra data flags: %r'%self.extra_data_flags)
|
||||||
|
ans.append('Primary index record: %d'%self.primary_index_record)
|
||||||
|
|
||||||
ans = '\n'.join(ans)
|
ans = '\n'.join(ans)
|
||||||
|
|
||||||
|
@ -7,8 +7,6 @@ __copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.cam> and \
|
|||||||
Kovid Goyal <kovid@kovidgoyal.net>'
|
Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from itertools import count
|
|
||||||
from itertools import izip
|
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
from struct import pack
|
from struct import pack
|
||||||
@ -1630,8 +1628,8 @@ class MobiWriter(object):
|
|||||||
self._write(title, pack('>HHIIIIII', 0, 0, now, now, 0, 0, 0, 0),
|
self._write(title, pack('>HHIIIIII', 0, 0, now, now, 0, 0, 0, 0),
|
||||||
'BOOK', 'MOBI', pack('>IIH', nrecords, 0, nrecords))
|
'BOOK', 'MOBI', pack('>IIH', nrecords, 0, nrecords))
|
||||||
offset = self._tell() + (8 * nrecords) + 2
|
offset = self._tell() + (8 * nrecords) + 2
|
||||||
for id, record in izip(count(), self._records):
|
for i, record in enumerate(self._records):
|
||||||
self._write(pack('>I', offset), '\0', pack('>I', id)[1:])
|
self._write(pack('>I', offset), '\0', pack('>I', 2*i)[1:])
|
||||||
offset += len(record)
|
offset += len(record)
|
||||||
self._write('\0\0')
|
self._write('\0\0')
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ class ViewAction(InterfaceAction):
|
|||||||
ac = self.view_specific_action = QAction(_('View specific format'),
|
ac = self.view_specific_action = QAction(_('View specific format'),
|
||||||
self.gui)
|
self.gui)
|
||||||
self.qaction.setMenu(self.view_menu)
|
self.qaction.setMenu(self.view_menu)
|
||||||
ac.setShortcut((Qt.ControlModifier if isosx else Qt.AltModifier)+Qt.Key_V)
|
ac.setShortcut(Qt.AltModifier+Qt.Key_V)
|
||||||
ac.triggered.connect(self.view_specific_format, type=Qt.QueuedConnection)
|
ac.triggered.connect(self.view_specific_format, type=Qt.QueuedConnection)
|
||||||
ac = self.view_action = QAction(self.qaction.icon(),
|
ac = self.view_action = QAction(self.qaction.icon(),
|
||||||
self.qaction.text(), self.gui)
|
self.qaction.text(), self.gui)
|
||||||
|
@ -205,6 +205,7 @@ class SearchBar(QWidget): # {{{
|
|||||||
x.setObjectName("search_option_button")
|
x.setObjectName("search_option_button")
|
||||||
l.addWidget(x)
|
l.addWidget(x)
|
||||||
x.setToolTip(_("Change the way searching for books works"))
|
x.setToolTip(_("Change the way searching for books works"))
|
||||||
|
x.setVisible(False)
|
||||||
|
|
||||||
x = parent.saved_search = SavedSearchBox(self)
|
x = parent.saved_search = SavedSearchBox(self)
|
||||||
x.setMaximumSize(QSize(150, 16777215))
|
x.setMaximumSize(QSize(150, 16777215))
|
||||||
|
@ -487,7 +487,13 @@ menu, choose "Validate fonts".
|
|||||||
I downloaded the installer, but it is not working?
|
I downloaded the installer, but it is not working?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Downloading from the internet can sometimes result in a corrupted download. If the |app| installer you downloaded is not opening, try downloading it again. If re-downloading it does not work, download it from `an alternate location <http://sourceforge.net/projects/calibre/files/>`_. If the installer still doesn't work, then something on your computer is preventing it from running. Try rebooting your computer and running a registry cleaner like `Wise registry cleaner <http://www.wisecleaner.com>`_. Best place to ask for more help is in the `forums <http://www.mobileread.com/forums/usercp.php>`_.
|
Downloading from the internet can sometimes result in a corrupted download. If the |app| installer you downloaded is not opening, try downloading it again. If re-downloading it does not work, download it from `an alternate location <http://sourceforge.net/projects/calibre/files/>`_. If the installer still doesn't work, then something on your computer is preventing it from running.
|
||||||
|
|
||||||
|
* Try temporarily disabling your antivirus program (Microsoft Security Essentials, or Kaspersky or Norton or McAfee or whatever). This is most likely the culprit if the upgrade process is hanging in the middle.
|
||||||
|
* Try rebooting your computer and running a registry cleaner like `Wise registry cleaner <http://www.wisecleaner.com>`_.
|
||||||
|
* Try downloading the installer with an alternate browser. For example if you are using Internet Explorer, try using Firefox or Chrome instead.
|
||||||
|
|
||||||
|
Best place to ask for more help is in the `forums <http://www.mobileread.com/forums/forumdisplay.php?f=166>`_.
|
||||||
|
|
||||||
My antivirus program claims |app| is a virus/trojan?
|
My antivirus program claims |app| is a virus/trojan?
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -130,7 +130,14 @@ def utcnow():
|
|||||||
return datetime.utcnow().replace(tzinfo=_utc_tz)
|
return datetime.utcnow().replace(tzinfo=_utc_tz)
|
||||||
|
|
||||||
def utcfromtimestamp(stamp):
|
def utcfromtimestamp(stamp):
|
||||||
return datetime.utcfromtimestamp(stamp).replace(tzinfo=_utc_tz)
|
try:
|
||||||
|
return datetime.utcfromtimestamp(stamp).replace(tzinfo=_utc_tz)
|
||||||
|
except ValueError:
|
||||||
|
# Raised if stamp if out of range for the platforms gmtime function
|
||||||
|
# We print the error for debugging, but otherwise ignore it
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
return utcnow()
|
||||||
|
|
||||||
def format_date(dt, format, assume_utc=False, as_utc=False):
|
def format_date(dt, format, assume_utc=False, as_utc=False):
|
||||||
''' Return a date formatted as a string using a subset of Qt's formatting codes '''
|
''' Return a date formatted as a string using a subset of Qt's formatting codes '''
|
||||||
|
Loading…
x
Reference in New Issue
Block a user