mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
sync with Kovid's branch
This commit is contained in:
commit
9fa0715276
@ -19,6 +19,54 @@
|
||||
# new recipes:
|
||||
# - title:
|
||||
|
||||
- version: 0.9.4
|
||||
date: 2012-10-26
|
||||
|
||||
new features:
|
||||
- title: "Conversion: Add an option to embed a font family into the book."
|
||||
description: "The embedded font is used as the base font for all text that does not specify its own font family in the input document. Works only with output formats that support font embedding, principally EPUB/AZW3. Option is found under Look & Feel in the conversion dialog. You can ensure that the font is used for all text, regardless of the input document's styles by filtering out font family styles via the Filter Style Information option in the Conversion dialog."
|
||||
type: major
|
||||
|
||||
- title: "When changing the title/author of a book, use hard links instead of copying the books' files, for a large speedup. Only works on filesystems that support hardlinks."
|
||||
|
||||
- title: "Linux installer: Resume interrupted downloads and verify the SHA-512 signature of the downloaded file before installing it."
|
||||
|
||||
bug fixes:
|
||||
- title: "Windows: Check if any of the files of a book are in use before changing the title/author, this prevents the creation of duplicate files if one of the files is open in another program"
|
||||
|
||||
- title: "Kobo driver: Fix the ondevice status for some books getting lost."
|
||||
tickets: [1069403]
|
||||
|
||||
- title: "Catalogs: Fix regression that broke use of prefix rules."
|
||||
tickets: [1070086]
|
||||
|
||||
- title: "Tag Browser: Fix sorting incorrect for accented letters"
|
||||
tickets: [1069835]
|
||||
|
||||
- title: "Make the bundled Liberation fonts available on all platforms for embedding"
|
||||
|
||||
- title: "Use mimetype for fonts from the EPUB 3 specification"
|
||||
|
||||
- title: "Get Books: Handle website change that broke the SONY Store plugin"
|
||||
|
||||
- title: "Generate cover: If the default font cannot render characters in the metadata (for example for east asian languages) try to automatically find a font on the system that is capable of rendering the characters"
|
||||
|
||||
- title: "Fix regression that broke certain types of CSS selectors."
|
||||
tickets: [1068937]
|
||||
|
||||
- title: "Use font-weight:bold instead of font-weight:bolder for the <b> and <strong> tags as ADE cant handle bolder when embedded fonts are used"
|
||||
|
||||
improved recipes:
|
||||
- New York Post
|
||||
- PC World
|
||||
- TIME Magazine
|
||||
- Associated Press
|
||||
|
||||
new recipes:
|
||||
- title: Yazihane
|
||||
author: A Erdogan
|
||||
|
||||
|
||||
- version: 0.9.3
|
||||
date: 2012-10-19
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 85 KiB |
BIN
manual/images/sg_pref.png
Normal file
BIN
manual/images/sg_pref.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 KiB |
@ -65,7 +65,7 @@ You create the custom column in the usual way, using Preferences -> Add your own
|
||||
|
||||
Then after restarting |app|, you must tell |app| that the column is to be treated as a hierarchy. Go to Preferences -> Look and Feel -> Tag Browser and enter the lookup name "#genre" into the "Categories with hierarchical items" box. Press Apply, and you are done with setting up.
|
||||
|
||||
.. image:: images/sg_pref.jpg
|
||||
.. image:: images/sg_pref.png
|
||||
:align: center
|
||||
|
||||
At the point there are no genres in the column. We are left with the last step: how to apply a genre to a book. A genre does not exist in |app| until it appears on at least one book. To learn how to apply a genre for the first time, we must go into some detail about what a genre looks like in the metadata for a book.
|
||||
|
@ -38,8 +38,10 @@ class TheAtlantic(BasicNewsRecipe):
|
||||
self.timefmt = ' [%s]'%ds
|
||||
|
||||
cover = soup.find('img', src=True, attrs={'class':'cover'})
|
||||
|
||||
if cover is not None:
|
||||
self.cover_url = cover['src'].replace(' ', '%20')
|
||||
self.cover_url = re.sub('\s','%20',re.sub('jpg.*','jpg',cover['src']))
|
||||
self.log(self.cover_url)
|
||||
|
||||
feeds = []
|
||||
seen_titles = set([])
|
||||
@ -47,18 +49,16 @@ class TheAtlantic(BasicNewsRecipe):
|
||||
section_title = self.tag_to_string(section.find('h2'))
|
||||
self.log('Found section:', section_title)
|
||||
articles = []
|
||||
for post in section.findAll('div', attrs={'class':lambda x : x and
|
||||
'post' in x}):
|
||||
h = post.find(['h3', 'h4'])
|
||||
title = self.tag_to_string(h)
|
||||
for post in section.findAll('h3', attrs={'class':'headline'}):
|
||||
a = post.find('a', href=True)
|
||||
title = self.tag_to_string(a)
|
||||
if title in seen_titles:
|
||||
continue
|
||||
seen_titles.add(title)
|
||||
a = post.find('a', href=True)
|
||||
url = a['href']
|
||||
if url.startswith('/'):
|
||||
url = 'http://www.theatlantic.com'+url
|
||||
p = post.find('p', attrs={'class':'dek'})
|
||||
p = post.parent.find('p', attrs={'class':'dek'})
|
||||
desc = None
|
||||
self.log('\tFound article:', title, 'at', url)
|
||||
if p is not None:
|
||||
@ -69,19 +69,29 @@ class TheAtlantic(BasicNewsRecipe):
|
||||
if articles:
|
||||
feeds.append((section_title, articles))
|
||||
|
||||
poems = []
|
||||
self.log('Found section: Poems')
|
||||
pd = soup.find('h2', text='Poetry').parent.parent
|
||||
for poem in pd.findAll('h4'):
|
||||
title = self.tag_to_string(poem)
|
||||
url = poem.find('a')['href']
|
||||
rightContent=soup.find('div', attrs = {'class':'rightContent'})
|
||||
for module in rightContent.findAll('div', attrs={'class':'module'}):
|
||||
section_title = self.tag_to_string(module.find('h2'))
|
||||
articles = []
|
||||
for post in module.findAll('div', attrs={'class':'post'}):
|
||||
a = post.find('a', href=True)
|
||||
title = self.tag_to_string(a)
|
||||
if title in seen_titles:
|
||||
continue
|
||||
seen_titles.add(title)
|
||||
url = a['href']
|
||||
if url.startswith('/'):
|
||||
url = 'http://www.theatlantic.com' + url
|
||||
url = 'http://www.theatlantic.com'+url
|
||||
p = post.parent.find('p', attrs={'class':'dek'})
|
||||
desc = None
|
||||
self.log('\tFound article:', title, 'at', url)
|
||||
poems.append({'title':title, 'url':url, 'description':'',
|
||||
'date':''})
|
||||
if poems:
|
||||
feeds.append(('Poems', poems))
|
||||
if p is not None:
|
||||
desc = self.tag_to_string(p)
|
||||
self.log('\t\t', desc)
|
||||
articles.append({'title':title, 'url':url, 'description':desc, 'date':''})
|
||||
if articles:
|
||||
feeds.append((section_title, articles))
|
||||
|
||||
|
||||
return feeds
|
||||
|
||||
@ -100,4 +110,3 @@ class TheAtlantic(BasicNewsRecipe):
|
||||
table.replaceWith(div)
|
||||
|
||||
return soup
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2010-2012, Darko Miletic <darko.miletic at gmail.com>'
|
||||
__copyright__ = '2010-2011, Darko Miletic <darko.miletic at gmail.com>'
|
||||
'''
|
||||
www.ft.com/uk-edition
|
||||
'''
|
||||
@ -42,8 +42,7 @@ class FinancialTimes(BasicNewsRecipe):
|
||||
def get_browser(self):
|
||||
br = BasicNewsRecipe.get_browser()
|
||||
br.open(self.INDEX)
|
||||
if self.username is not None and self.password is not None:
|
||||
br.open(self.LOGIN2)
|
||||
br.open(self.LOGIN)
|
||||
br.select_form(name='loginForm')
|
||||
br['username'] = self.username
|
||||
br['password'] = self.password
|
||||
@ -51,15 +50,10 @@ class FinancialTimes(BasicNewsRecipe):
|
||||
return br
|
||||
|
||||
keep_only_tags = [
|
||||
dict(name='div' , attrs={'class':['fullstory fullstoryHeader', 'ft-story-header']})
|
||||
,dict(name='div' , attrs={'class':'standfirst'})
|
||||
,dict(name='div' , attrs={'id' :'storyContent'})
|
||||
,dict(name='div' , attrs={'class':['ft-story-body','index-detail']})
|
||||
,dict(name='div' , attrs={'class':['ft-story-body','index-detail']})
|
||||
,dict(name='h2' , attrs={'class':'entry-title'} )
|
||||
,dict(name='span', attrs={'class':lambda x: x and 'posted-on' in x.split()} )
|
||||
,dict(name='span', attrs={'class':'author_byline'} )
|
||||
,dict(name='div' , attrs={'class':'entry-content'} )
|
||||
dict(name='div', attrs={'class':['fullstory fullstoryHeader', 'ft-story-header']})
|
||||
,dict(name='div', attrs={'class':'standfirst'})
|
||||
,dict(name='div', attrs={'id' :'storyContent'})
|
||||
,dict(name='div', attrs={'class':['ft-story-body','index-detail']})
|
||||
]
|
||||
remove_tags = [
|
||||
dict(name='div', attrs={'id':'floating-con'})
|
||||
@ -88,10 +82,14 @@ class FinancialTimes(BasicNewsRecipe):
|
||||
if self.test and count > 2:
|
||||
return articles
|
||||
rawlink = item['href']
|
||||
if rawlink.startswith('http://'):
|
||||
url = rawlink
|
||||
if not rawlink.startswith('http://'):
|
||||
else:
|
||||
url = self.PREFIX + rawlink
|
||||
try:
|
||||
urlverified = self.browser.open_novisit(url).geturl() # resolve redirect.
|
||||
except:
|
||||
continue
|
||||
title = self.tag_to_string(item)
|
||||
date = strftime(self.timefmt)
|
||||
articles.append({
|
||||
@ -110,20 +108,21 @@ class FinancialTimes(BasicNewsRecipe):
|
||||
wide = soup.find('div',attrs={'class':'wide'})
|
||||
if not wide:
|
||||
return feeds
|
||||
allsections = wide.findAll(attrs={'class':lambda x: x and 'footwell' in x.split()})
|
||||
if not allsections:
|
||||
strest = wide.findAll('h3', attrs={'class':'section'})
|
||||
if not strest:
|
||||
return feeds
|
||||
st = wide.findAll('h4',attrs={'class':'section-no-arrow'})
|
||||
if st:
|
||||
st.extend(strest)
|
||||
count = 0
|
||||
for item in allsections:
|
||||
for item in st:
|
||||
count = count + 1
|
||||
if self.test and count > 2:
|
||||
return feeds
|
||||
fitem = item.h3
|
||||
if not fitem:
|
||||
fitem = item.h4
|
||||
ftitle = self.tag_to_string(fitem)
|
||||
ftitle = self.tag_to_string(item)
|
||||
self.report_progress(0, _('Fetching feed')+' %s...'%(ftitle))
|
||||
feedarts = self.get_artlinks(item.ul)
|
||||
if item.parent.ul is not None:
|
||||
feedarts = self.get_artlinks(item.parent.ul)
|
||||
feeds.append((ftitle,feedarts))
|
||||
return feeds
|
||||
|
||||
@ -170,8 +169,10 @@ class FinancialTimes(BasicNewsRecipe):
|
||||
except:
|
||||
print "Retrying download..."
|
||||
count += 1
|
||||
tfile = PersistentTemporaryFile('_fa.html')
|
||||
tfile.write(html)
|
||||
tfile.close()
|
||||
self.temp_files.append(tfile)
|
||||
return tfile.name
|
||||
self.temp_files.append(PersistentTemporaryFile('_fa.html'))
|
||||
self.temp_files[-1].write(html)
|
||||
self.temp_files[-1].close()
|
||||
return self.temp_files[-1].name
|
||||
|
||||
def cleanup(self):
|
||||
self.browser.open('https://registration.ft.com/registration/login/logout?location=')
|
||||
|
@ -1,5 +1,4 @@
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
from calibre.ebooks.BeautifulSoup import BeautifulSoup
|
||||
|
||||
class NewYorkTimesBookReview(BasicNewsRecipe):
|
||||
title = u'New York Times Book Review'
|
||||
@ -7,50 +6,16 @@ class NewYorkTimesBookReview(BasicNewsRecipe):
|
||||
__author__ = 'Krittika Goyal'
|
||||
oldest_article = 8 #days
|
||||
max_articles_per_feed = 1000
|
||||
recursions = 2
|
||||
#recursions = 2
|
||||
#encoding = 'latin1'
|
||||
use_embedded_content = False
|
||||
|
||||
no_stylesheets = True
|
||||
auto_cleanup = True
|
||||
|
||||
remove_stylesheets = True
|
||||
#remove_tags_before = dict(name='h1', attrs={'class':'heading'})
|
||||
remove_tags_after = dict(name='div', attrs={'id':'authorId'})
|
||||
remove_tags = [
|
||||
dict(name='iframe'),
|
||||
dict(name=['div', 'a'], attrs={'class':['enlargeThis', 'jumpLink']}),
|
||||
dict(name='div', attrs={'id':['sidebarArticles', 'toolsRight']}),
|
||||
#dict(name='ul', attrs={'class':'article-tools'}),
|
||||
#dict(name='ul', attrs={'class':'articleTools'}),
|
||||
]
|
||||
match_regexps = [
|
||||
r'http://www.nytimes.com/.+pagewanted=[2-9]+'
|
||||
]
|
||||
|
||||
feeds = [
|
||||
('New York Times Sunday Book Review',
|
||||
('New York Times Sunday Book Review',
|
||||
'http://feeds.nytimes.com/nyt/rss/SundayBookReview'),
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
def preprocess_html(self, soup):
|
||||
story = soup.find(name='div', attrs={'id':'article'})
|
||||
#td = heading.findParent(name='td')
|
||||
#td.extract()
|
||||
soup = BeautifulSoup('<html><head><title>t</title></head><body></body></html>')
|
||||
body = soup.find(name='body')
|
||||
body.insert(0, story)
|
||||
#for x in soup.findAll(name='p', text=lambda x:x and '-->' in x):
|
||||
#p = x.findParent('p')
|
||||
#if p is not None:
|
||||
#p.extract()
|
||||
return soup
|
||||
|
||||
def postprocess_html(self, soup, first):
|
||||
for div in soup.findAll(id='pageLinks'):
|
||||
div.extract()
|
||||
if not first:
|
||||
h1 = soup.find('h1')
|
||||
if h1 is not None:
|
||||
h1.extract()
|
||||
t = soup.find(attrs={'class':'timestamp'})
|
||||
if t is not None:
|
||||
t.extract()
|
||||
return soup
|
||||
|
@ -4,7 +4,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
__appname__ = u'calibre'
|
||||
numeric_version = (0, 9, 3)
|
||||
numeric_version = (0, 9, 4)
|
||||
__version__ = u'.'.join(map(unicode, numeric_version))
|
||||
__author__ = u"Kovid Goyal <kovid@kovidgoyal.net>"
|
||||
|
||||
|
@ -184,6 +184,11 @@ class CSSFlattener(object):
|
||||
faces = fontconfig.fonts_for_family(family)
|
||||
if not faces or not u'normal' in faces:
|
||||
msg = (u'No embeddable fonts found for family: %r'%self.opts.embed_font_family)
|
||||
if faces:
|
||||
msg = (u'The selected font %s has no Regular typeface, only'
|
||||
' %s faces, it cannot be used.')%(
|
||||
self.opts.embed_font_family,
|
||||
', '.join(faces.iterkeys()))
|
||||
if failure_critical:
|
||||
raise ValueError(msg)
|
||||
self.oeb.log.warn(msg)
|
||||
|
@ -504,7 +504,11 @@ from the value in the box</string>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="restore_original">
|
||||
<property name="toolTip">
|
||||
<string>When doing a same format to same format conversion, for e.g., EPUB to EPUB, calibre saves the original EPUB as ORIGINAL_EPUB. This option tells calibre to restore the EPUB from ORIGINAL_EPUB. Useful if you did a bulk conversion of a large number of books and something went wrong.</string>
|
||||
<string>When doing a same format to same format conversion,
|
||||
for e.g., EPUB to EPUB, calibre saves the original EPUB
|
||||
as ORIGINAL_EPUB. This option tells calibre to restore
|
||||
the EPUB from ORIGINAL_EPUB. Useful if you did a bulk
|
||||
conversion of a large number of books and something went wrong.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Restore pre conversion &originals, if available</string>
|
||||
|
@ -13,6 +13,7 @@ from PyQt4.Qt import (QFontInfo, QFontMetrics, Qt, QFont, QFontDatabase, QPen,
|
||||
QToolButton, QGridLayout, QListView, QWidget, QDialogButtonBox, QIcon,
|
||||
QHBoxLayout, QLabel, QModelIndex)
|
||||
|
||||
from calibre.gui2 import error_dialog
|
||||
from calibre.utils.icu import sort_key
|
||||
|
||||
def writing_system_for_font(font):
|
||||
@ -173,6 +174,20 @@ class FontFamilyDialog(QDialog):
|
||||
if idx == 0: return None
|
||||
return self.families[idx]
|
||||
|
||||
def accept(self):
|
||||
ff = self.font_family
|
||||
if ff:
|
||||
from calibre.utils.fonts import fontconfig
|
||||
faces = fontconfig.fonts_for_family(ff) or {}
|
||||
faces = frozenset(faces.iterkeys())
|
||||
if 'normal' not in faces:
|
||||
error_dialog(self, _('Not a useable font'),
|
||||
_('The %s font family does not have a Regular typeface, so it'
|
||||
' cannot be used. It has only the "%s" face(s).')%(
|
||||
ff, ', '.join(faces)), show=True)
|
||||
return
|
||||
QDialog.accept(self)
|
||||
|
||||
class FontFamilyChooser(QWidget):
|
||||
|
||||
family_changed = pyqtSignal(object)
|
||||
|
@ -646,12 +646,13 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
||||
spath = os.path.join(self.library_path, *current_path.split('/'))
|
||||
tpath = os.path.join(self.library_path, *path.split('/'))
|
||||
|
||||
wam = WindowsAtomicFolderMove(spath) if iswindows and current_path else None
|
||||
source_ok = current_path and os.path.exists(spath)
|
||||
wam = WindowsAtomicFolderMove(spath) if iswindows and source_ok else None
|
||||
try:
|
||||
if not os.path.exists(tpath):
|
||||
os.makedirs(tpath)
|
||||
|
||||
if current_path and os.path.exists(spath): # Migrate existing files
|
||||
if source_ok: # Migrate existing files
|
||||
self.copy_cover_to(id, os.path.join(tpath, 'cover.jpg'),
|
||||
index_is_id=True, windows_atomic_move=wam,
|
||||
use_hardlink=True)
|
||||
@ -669,7 +670,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
||||
self.conn.commit()
|
||||
self.data.set(id, self.FIELD_MAP['path'], path, row_is_id=True)
|
||||
# Delete not needed directories
|
||||
if current_path and os.path.exists(spath):
|
||||
if source_ok:
|
||||
if not samefile(spath, tpath):
|
||||
if wam is not None:
|
||||
wam.delete_originals()
|
||||
@ -1432,7 +1433,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
||||
if use_hardlink:
|
||||
try:
|
||||
hardlink_file(path, dest)
|
||||
return
|
||||
return True
|
||||
except:
|
||||
pass
|
||||
with lopen(dest, 'wb') as d:
|
||||
|
@ -4,9 +4,9 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: calibre 0.9.3\n"
|
||||
"POT-Creation-Date: 2012-10-24 09:36+IST\n"
|
||||
"PO-Revision-Date: 2012-10-24 09:36+IST\n"
|
||||
"Project-Id-Version: calibre 0.9.4\n"
|
||||
"POT-Creation-Date: 2012-10-26 09:57+IST\n"
|
||||
"PO-Revision-Date: 2012-10-26 09:57+IST\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: LANGUAGE\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@ -173,12 +173,12 @@ msgstr ""
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:586
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:594
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:605
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:2273
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:2427
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:2857
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3504
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3506
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3643
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:2274
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:2428
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:2858
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3505
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3507
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3644
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server/content.py:250
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server/content.py:251
|
||||
#: /home/kovid/work/calibre/src/calibre/library/server/mobile.py:247
|
||||
@ -882,26 +882,26 @@ msgstr ""
|
||||
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:666
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:67
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:668
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:1061
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:1062
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/formatter_functions.py:887
|
||||
#: /home/kovid/work/calibre/src/calibre/utils/formatter_functions.py:910
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/db/fields.py:163
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:1216
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:1217
|
||||
msgid "Main"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/db/fields.py:165
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:77
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:1218
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:1219
|
||||
msgid "Card A"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/db/fields.py:167
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:79
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:1220
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:1221
|
||||
msgid "Card B"
|
||||
msgstr ""
|
||||
|
||||
@ -1048,14 +1048,14 @@ msgstr ""
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:1199
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:371
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:384
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3361
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3362
|
||||
#: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:187
|
||||
msgid "News"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2770
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3317
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3335
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3318
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3336
|
||||
msgid "Catalog"
|
||||
msgstr ""
|
||||
|
||||
@ -1099,10 +1099,10 @@ msgstr ""
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:128
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:131
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:348
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:1307
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:1311
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:1315
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:1635
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:1319
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:1323
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:1642
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:155
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:144
|
||||
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:147
|
||||
@ -11001,6 +11001,10 @@ msgstr ""
|
||||
msgid "Choose &font family"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/font_family_chooser.py:196
|
||||
msgid "Clear the font family"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/init.py:108
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/look_feel_ui.py:296
|
||||
msgid "Cover Browser"
|
||||
@ -12216,7 +12220,7 @@ msgstr ""
|
||||
msgid ""
|
||||
"If set, this option will causes calibre to check if a file\n"
|
||||
" being auto-added is already in the calibre library.\n"
|
||||
" If it is, a meesage will pop up asking you whether\n"
|
||||
" If it is, a message will pop up asking you whether\n"
|
||||
" you want to add it anyway."
|
||||
msgstr ""
|
||||
|
||||
@ -15287,7 +15291,7 @@ msgid "Options to customize the ebook viewer"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/config.py:30
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1106
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1107
|
||||
msgid "Remember last used window size"
|
||||
msgstr ""
|
||||
|
||||
@ -15854,35 +15858,35 @@ msgstr ""
|
||||
msgid "Loading ebook..."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:977
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:978
|
||||
msgid "Could not open ebook"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:978
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:979
|
||||
msgid "Unknown error"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1093
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1094
|
||||
msgid "Options to control the ebook viewer"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1100
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1101
|
||||
msgid "If specified, viewer window will try to come to the front when started."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1103
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1104
|
||||
msgid "If specified, viewer window will try to open full screen when started."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1108
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1109
|
||||
msgid "Print javascript alert and console messages to the console"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1110
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1111
|
||||
msgid "The position at which to open the specified book. The position is a location as displayed in the top left corner of the viewer."
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1117
|
||||
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:1118
|
||||
msgid ""
|
||||
"%prog [options] file\n"
|
||||
"\n"
|
||||
@ -17358,17 +17362,17 @@ msgstr ""
|
||||
msgid "creating custom column "
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3669
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3670
|
||||
#, python-format
|
||||
msgid "<p>Migrating old database to ebook library in %s<br><center>"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3698
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3699
|
||||
#, python-format
|
||||
msgid "Copying <b>%s</b>"
|
||||
msgstr ""
|
||||
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3715
|
||||
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3716
|
||||
msgid "Compacting database"
|
||||
msgstr ""
|
||||
|
||||
|
@ -314,6 +314,17 @@ class WindowsAtomicFolderMove(object):
|
||||
break
|
||||
f.write(raw)
|
||||
|
||||
def release_file(self, path):
|
||||
key = None
|
||||
for p, h in self.handle_map.iteritems():
|
||||
if samefile_windows(path, p):
|
||||
key = (p, h)
|
||||
break
|
||||
if key is not None:
|
||||
import win32file
|
||||
win32file.CloseHandle(key[1])
|
||||
self.handle_map.pop(key[0])
|
||||
|
||||
def close_handles(self):
|
||||
import win32file
|
||||
for h in self.handle_map.itervalues():
|
||||
|
Loading…
x
Reference in New Issue
Block a user