Get Books: Remove epub bud store. Add Ozon.ru store. Fix broken amazon UK and DE stores. Fixes #816091 (Epub bud store steals ebooks. Do not direct people there.)

This commit is contained in:
Kovid Goyal 2011-07-27 00:16:28 -06:00
commit 42f9160af0
10 changed files with 342 additions and 305 deletions

View File

@ -1228,17 +1228,6 @@ class StoreEbookscomStore(StoreBase):
formats = ['EPUB', 'LIT', 'MOBI', 'PDF']
affiliate = True
#class StoreEPubBuyDEStore(StoreBase):
# name = 'EPUBBuy DE'
# author = 'Charles Haley'
# description = u'Bei EPUBBuy.com finden Sie ausschliesslich eBooks im weitverbreiteten EPUB-Format und ohne DRM. So haben Sie die freie Wahl, wo Sie Ihr eBook lesen: Tablet, eBook-Reader, Smartphone oder einfach auf Ihrem PC. So macht eBook-Lesen Spaß!'
# actual_plugin = 'calibre.gui2.store.stores.epubbuy_de_plugin:EPubBuyDEStore'
#
# drm_free_only = True
# headquarters = 'DE'
# formats = ['EPUB']
# affiliate = True
class StoreEBookShoppeUKStore(StoreBase):
name = 'ebookShoppe UK'
author = u'Charles Haley'
@ -1266,16 +1255,7 @@ class StoreEKnigiStore(StoreBase):
headquarters = 'BG'
formats = ['EPUB', 'PDF', 'HTML']
#affiliate = True
class StoreEpubBudStore(StoreBase):
name = 'ePub Bud'
description = 'Well, it\'s pretty much just "YouTube for Children\'s eBooks. A not-for-profit organization devoted to brining self published childrens books to the world.'
actual_plugin = 'calibre.gui2.store.stores.epubbud_plugin:EpubBudStore'
drm_free_only = True
headquarters = 'US'
formats = ['EPUB']
affiliate = True
class StoreFeedbooksStore(StoreBase):
name = 'Feedbooks'
@ -1311,6 +1291,7 @@ class StoreGoogleBooksStore(StoreBase):
headquarters = 'US'
formats = ['EPUB', 'PDF', 'TXT']
affiliate = True
class StoreGutenbergStore(StoreBase):
name = 'Project Gutenberg'
@ -1394,6 +1375,17 @@ class StoreOReillyStore(StoreBase):
headquarters = 'US'
formats = ['APK', 'DAISY', 'EPUB', 'MOBI', 'PDF']
class StoreOzonRUStore(StoreBase):
name = 'OZON.ru'
description = u'ebooks from OZON.ru'
actual_plugin = 'calibre.gui2.store.stores.ozon_ru_plugin:OzonRUStore'
author = 'Roman Mukhin'
drm_free_only = True
headquarters = 'RU'
formats = ['TXT', 'PDF', 'DJVU', 'RTF', 'DOC', 'JAR', 'FB2']
affiliate = True
class StorePragmaticBookshelfStore(StoreBase):
name = 'Pragmatic Bookshelf'
description = u'The Pragmatic Bookshelf\'s collection of programming and tech books avaliable as ebooks.'
@ -1491,10 +1483,8 @@ plugins += [
StoreEbookNLStore,
StoreEbookscomStore,
StoreEBookShoppeUKStore,
# StoreEPubBuyDEStore,
StoreEHarlequinStore,
StoreEKnigiStore,
StoreEpubBudStore,
StoreFeedbooksStore,
StoreFoylesUKStore,
StoreGandalfStore,
@ -1508,6 +1498,7 @@ plugins += [
StoreNextoStore,
StoreOpenBooksStore,
StoreOReillyStore,
StoreOzonRUStore,
StorePragmaticBookshelfStore,
StoreSmashwordsStore,
StoreVirtualoStore,

View File

@ -24,10 +24,9 @@ XPath = partial(etree.XPath, namespaces=NAMESPACES)
tostring = partial(etree.tostring, method='text', encoding=unicode)
def get_metadata(stream):
""" Return fb2 metadata as a L{MetaInformation} object """
''' Return fb2 metadata as a L{MetaInformation} object '''
root = _get_fbroot(stream)
book_title = _parse_book_title(root)
authors = _parse_authors(root)
@ -181,6 +180,7 @@ def _parse_series(root, mi):
def _parse_isbn(root, mi):
# some people try to put several isbn in this field, but it is not allowed. try to stick to the 1-st one in this case
isbn = XPath('normalize-space(//fb2:publish-info/fb2:isbn/text())')(root)
if isbn:
# some people try to put several isbn in this field, but it is not allowed. try to stick to the 1-st one in this case
if ',' in isbn:
isbn = isbn[:isbn.index(',')]
@ -232,4 +232,3 @@ def _get_fbroot(stream):
raw = xml_to_unicode(raw, strip_encoding_pats=True)[0]
root = etree.fromstring(raw, parser=parser)
return root

View File

@ -23,7 +23,8 @@ from calibre.utils.search_query_parser import SearchQueryParser
def comparable_price(text):
text = re.sub(r'[^0-9.,]', '', text)
if len(text) < 3 or text[-3] not in ('.', ','):
delimeter = (',', '.')
if len(text) < 3 or text[-3] not in delimeter:
text += '00'
text = re.sub(r'\D', '', text)
text = text.rjust(6, '0')
@ -334,6 +335,11 @@ class SearchFilter(SearchQueryParser):
}
for x in ('author', 'download', 'format'):
q[x+'s'] = q[x]
# make the price in query the same format as result
if location == 'price':
query = comparable_price(query)
for sr in self.srs:
for locvalue in locations:
accessor = q[locvalue]

View File

@ -45,24 +45,26 @@ class AmazonDEKindleStore(StorePlugin):
doc = html.fromstring(f.read())
# Amazon has two results pages.
is_shot = doc.xpath('boolean(//div[@id="shotgunMainResults"])')
# Horizontal grid of books.
if is_shot:
data_xpath = '//div[contains(@class, "result")]'
format_xpath = './/div[@class="productTitle"]/text()'
cover_xpath = './/div[@class="productTitle"]//img/@src'
# Vertical list of books.
else:
data_xpath = '//div[@class="productData"]'
# 20110725: seems that is_shot is gone.
# is_shot = doc.xpath('boolean(//div[@id="shotgunMainResults"])')
# # Horizontal grid of books.
# if is_shot:
# data_xpath = '//div[contains(@class, "result")]'
# format_xpath = './/div[@class="productTitle"]/text()'
# cover_xpath = './/div[@class="productTitle"]//img/@src'
# # Vertical list of books.
# else:
data_xpath = '//div[contains(@class, "result") and contains(@class, "product")]'
format_xpath = './/span[@class="format"]/text()'
cover_xpath = '../div[@class="productImage"]/a/img/@src'
cover_xpath = './/img[@class="productImage"]/@src'
# end is_shot else
for data in doc.xpath(data_xpath):
if counter <= 0:
break
# Even though we are searching digital-text only Amazon will still
# put in results for non Kindle books (author pages). Se we need
# put in results for non Kindle books (author pages). So we need
# to explicitly check if the item is a Kindle book and ignore it
# if it isn't.
format = ''.join(data.xpath(format_xpath))
@ -71,27 +73,17 @@ class AmazonDEKindleStore(StorePlugin):
# We must have an asin otherwise we can't easily reference the
# book later.
asin_href = None
asin_a = data.xpath('.//div[@class="productTitle"]/a[1]')
if asin_a:
asin_href = asin_a[0].get('href', '')
m = re.search(r'/dp/(?P<asin>.+?)(/|$)', asin_href)
if m:
asin = m.group('asin')
else:
continue
else:
continue
asin = ''.join(data.xpath("@name"))
cover_url = ''.join(data.xpath(cover_xpath))
title = ''.join(data.xpath('.//div[@class="productTitle"]/a/text()'))
title = ''.join(data.xpath('.//div[@class="title"]/a/text()'))
price = ''.join(data.xpath('.//div[@class="newPrice"]/span/text()'))
if is_shot:
author = format.split(' von ')[-1]
else:
author = ''.join(data.xpath('.//div[@class="productTitle"]/span[@class="ptBrand"]/text()'))
# if is_shot:
# author = format.split(' von ')[-1]
# else:
author = ''.join(data.xpath('.//div[@class="title"]/span[@class="ptBrand"]/text()'))
author = author.split('von ')[-1]
counter -= 1

View File

@ -42,48 +42,55 @@ class AmazonUKKindleStore(StorePlugin):
doc = html.fromstring(f.read())
# Amazon has two results pages.
is_shot = doc.xpath('boolean(//div[@id="shotgunMainResults"])')
# Horizontal grid of books.
if is_shot:
data_xpath = '//div[contains(@class, "result")]'
cover_xpath = './/div[@class="productTitle"]//img/@src'
# Vertical list of books.
else:
data_xpath = '//div[contains(@class, "product")]'
cover_xpath = './div[@class="productImage"]/a/img/@src'
# 20110725: seems that is_shot is gone.
# is_shot = doc.xpath('boolean(//div[@id="shotgunMainResults"])')
# # Horizontal grid of books.
# if is_shot:
# data_xpath = '//div[contains(@class, "result")]'
# format_xpath = './/div[@class="productTitle"]/text()'
# cover_xpath = './/div[@class="productTitle"]//img/@src'
# # Vertical list of books.
# else:
data_xpath = '//div[contains(@class, "result") and contains(@class, "product")]'
format_xpath = './/span[@class="format"]/text()'
cover_xpath = './/img[@class="productImage"]/@src'
# end is_shot else
for data in doc.xpath(data_xpath):
if counter <= 0:
break
# Even though we are searching digital-text only Amazon will still
# put in results for non Kindle books (author pages). So we need
# to explicitly check if the item is a Kindle book and ignore it
# if it isn't.
format = ''.join(data.xpath(format_xpath))
if 'kindle' not in format.lower():
continue
# We must have an asin otherwise we can't easily reference the
# book later.
asin = ''.join(data.xpath('./@name'))
if not asin:
continue
asin = ''.join(data.xpath("@name"))
cover_url = ''.join(data.xpath(cover_xpath))
title = ''.join(data.xpath('.//div[@class="productTitle"]/a/text()'))
title = ''.join(data.xpath('.//div[@class="title"]/a/text()'))
price = ''.join(data.xpath('.//div[@class="newPrice"]/span/text()'))
# if is_shot:
# author = format.split(' von ')[-1]
# else:
author = ''.join(data.xpath('.//div[@class="title"]/span[@class="ptBrand"]/text()'))
author = author.split('by ')[-1]
counter -= 1
s = SearchResult()
s.cover_url = cover_url.strip()
s.title = title.strip()
s.author = author.strip()
s.price = price.strip()
s.detail_item = asin.strip()
s.formats = ''
if is_shot:
# Amazon UK does not include the author on the grid layout
s.author = ''
self.get_details(s, timeout)
if s.formats != 'Kindle':
continue
else:
author = ''.join(data.xpath('.//div[@class="productTitle"]/span[@class="ptBrand"]/text()'))
s.author = author.split(' by ')[-1].strip()
s.formats = 'Kindle'
yield s

View File

@ -1,27 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import (unicode_literals, division, absolute_import, print_function)
__license__ = 'GPL 3'
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'
from calibre.gui2.store.basic_config import BasicStoreConfig
from calibre.gui2.store.opensearch_store import OpenSearchOPDSStore
from calibre.gui2.store.search_result import SearchResult
class EpubBudStore(BasicStoreConfig, OpenSearchOPDSStore):
open_search_url = 'http://www.epubbud.com/feeds/opensearch.xml'
web_url = 'http://www.epubbud.com/'
# http://www.epubbud.com/feeds/catalog.atom
def search(self, query, max_results=10, timeout=60):
for s in OpenSearchOPDSStore.search(self, query, max_results, timeout):
s.price = '$0.00'
s.drm = SearchResult.DRM_UNLOCKED
s.formats = 'EPUB'
# Download links are broken for this store.
s.downloads = {}
yield s

View File

@ -1,80 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import (unicode_literals, division, absolute_import, print_function)
__license__ = 'GPL 3'
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'
import urllib2
from contextlib import closing
from lxml import html
from PyQt4.Qt import QUrl
from calibre import browser
from calibre.gui2 import open_url
from calibre.gui2.store import StorePlugin
from calibre.gui2.store.basic_config import BasicStoreConfig
from calibre.gui2.store.search_result import SearchResult
from calibre.gui2.store.web_store_dialog import WebStoreDialog
class EPubBuyDEStore(BasicStoreConfig, StorePlugin):
def open(self, parent=None, detail_item=None, external=False):
url = 'http://klick.affiliwelt.net/klick.php?bannerid=47653&pid=32307&prid=2627'
url_details = ('http://klick.affiliwelt.net/klick.php?bannerid=47653'
'&pid=32307&prid=2627&prodid={0}')
if external or self.config.get('open_external', False):
if detail_item:
url = url_details.format(detail_item)
open_url(QUrl(url))
else:
detail_url = None
if detail_item:
detail_url = url_details.format(detail_item)
d = WebStoreDialog(self.gui, url, parent, detail_url)
d.setWindowTitle(self.name)
d.set_tags(self.config.get('tags', ''))
d.exec_()
def search(self, query, max_results=10, timeout=60):
url = 'http://www.epubbuy.com/search.php?search_query=' + urllib2.quote(query)
br = browser()
counter = max_results
with closing(br.open(url, timeout=timeout)) as f:
doc = html.fromstring(f.read())
for data in doc.xpath('//li[contains(@class, "ajax_block_product")]'):
if counter <= 0:
break
id = ''.join(data.xpath('./div[@class="center_block"]'
'/p[contains(text(), "artnr:")]/text()')).strip()
if not id:
continue
id = id[6:].strip()
if not id:
continue
cover_url = ''.join(data.xpath('./div[@class="center_block"]'
'/a[@class="product_img_link"]/img/@src'))
if cover_url:
cover_url = 'http://www.epubbuy.com' + cover_url
title = ''.join(data.xpath('./div[@class="center_block"]'
'/a[@class="product_img_link"]/@title'))
author = ''.join(data.xpath('./div[@class="center_block"]/a[2]/text()'))
price = ''.join(data.xpath('.//span[@class="price"]/text()'))
counter -= 1
s = SearchResult()
s.cover_url = cover_url
s.title = title.strip()
s.author = author.strip()
s.price = price
s.drm = SearchResult.DRM_UNLOCKED
s.detail_item = id
s.formats = 'ePub'
yield s

View File

@ -6,6 +6,7 @@ __license__ = 'GPL 3'
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en'
import random
import urllib
from contextlib import closing
@ -23,7 +24,24 @@ from calibre.gui2.store.web_store_dialog import WebStoreDialog
class GoogleBooksStore(BasicStoreConfig, StorePlugin):
def open(self, parent=None, detail_item=None, external=False):
url = 'http://books.google.com/'
aff_id = {
'lid': '41000000033185143',
'pubid': '21000000000352219',
'ganpub': 'k352219',
'ganclk': 'GOOG_1335334761',
}
# Use Kovid's affiliate id 30% of the time.
if random.randint(1, 10) in (1, 2, 3):
aff_id = {
'lid': '41000000031855266',
'pubid': '21000000000352583',
'ganpub': 'k352583',
'ganclk': 'GOOG_1335335464',
}
url = 'http://gan.doubleclick.net/gan_click?lid=%(lid)s&pubid=%(pubid)s' % aff_id
if detail_item:
detail_item += '&ganpub=%(ganpub)s&ganclk=%(ganclk)s' % aff_id
if external or self.config.get('open_external', False):
open_url(QUrl(url_slash_cleaner(detail_item if detail_item else url)))

View File

@ -0,0 +1,126 @@
# -*- coding: utf-8 -*-
from __future__ import (unicode_literals, division, absolute_import, print_function)
__license__ = 'GPL 3'
__copyright__ = '2011, Roman Mukhin <ramses_ru at hotmail.com>'
__docformat__ = 'restructuredtext en'
import random
import re
import urllib2
from contextlib import closing
from lxml import etree, html
from PyQt4.Qt import QUrl
from calibre import browser, url_slash_cleaner
from calibre.ebooks.chardet import xml_to_unicode
from calibre.gui2 import open_url
from calibre.gui2.store import StorePlugin
from calibre.gui2.store.basic_config import BasicStoreConfig
from calibre.gui2.store.search_result import SearchResult
from calibre.gui2.store.web_store_dialog import WebStoreDialog
class OzonRUStore(BasicStoreConfig, StorePlugin):
shop_url = 'http://www.ozon.ru'
def open(self, parent=None, detail_item=None, external=False):
aff_id = '?partner=romuk'
# Use Kovid's affiliate id 30% of the time.
if random.randint(1, 10) in (1, 2, 3):
aff_id = '?partner=kovidgoyal'
url = self.shop_url + aff_id
detail_url = None
if detail_item:
# http://www.ozon.ru/context/detail/id/3037277/
detail_url = self.shop_url + '/context/detail/id/' + urllib2.quote(detail_item) + aff_id
if external or self.config.get('open_external', False):
open_url(QUrl(url_slash_cleaner(detail_url if detail_url else url)))
else:
d = WebStoreDialog(self.gui, url, parent, detail_url)
d.setWindowTitle(self.name)
d.set_tags(self.config.get('tags', ''))
d.exec_()
def search(self, query, max_results=10, timeout=60):
search_url = self.shop_url + '/webservice/webservice.asmx/SearchWebService?'\
'searchText=%s&searchContext=ebook' % urllib2.quote(query)
counter = max_results
br = browser()
with closing(br.open(search_url, timeout=timeout)) as f:
raw = xml_to_unicode(f.read(), strip_encoding_pats=True, assume_utf8=True)[0]
doc = etree.fromstring(raw)
for data in doc.xpath('//*[local-name() = "SearchItems"]'):
if counter <= 0:
break
counter -= 1
xp_template = 'normalize-space(./*[local-name() = "{0}"]/text())'
s = SearchResult()
s.detail_item = data.xpath(xp_template.format('ID'))
s.title = data.xpath(xp_template.format('Name'))
s.author = data.xpath(xp_template.format('Author'))
s.price = data.xpath(xp_template.format('Price'))
s.cover_url = data.xpath(xp_template.format('Picture'))
if re.match("^\d+?\.\d+?$", s.price):
s.price = u'{:.2F} руб.'.format(float(s.price))
yield s
def get_details(self, search_result, timeout=60):
url = self.shop_url + '/context/detail/id/' + urllib2.quote(search_result.detail_item)
br = browser()
result = False
with closing(br.open(url, timeout=timeout)) as f:
doc = html.fromstring(f.read())
# example where we are going to find formats
# <div class="box">
# ...
# <b>Доступные&nbsp;форматы:</b>
# <div class="vertpadd">.epub, .fb2, .pdf, .pdf, .txt</div>
# ...
# </div>
xpt = u'normalize-space(//div[@class="box"]//*[contains(normalize-space(text()), "Доступные форматы:")][1]/following-sibling::div[1]/text())'
formats = doc.xpath(xpt)
if formats:
result = True
search_result.drm = SearchResult.DRM_UNLOCKED
search_result.formats = ', '.join(_parse_ebook_formats(formats))
# unfortunately no direct links to download books (only buy link)
# search_result.downloads['BF2'] = self.shop_url + '/order/digitalorder.aspx?id=' + + urllib2.quote(search_result.detail_item)
return result
def _parse_ebook_formats(formatsStr):
'''
Creates a list with displayable names of the formats
:param formatsStr: string with comma separated book formats
as it provided by ozon.ru
:return: a list with displayable book formats
'''
formatsUnstruct = formatsStr.lower()
formats = []
if 'epub' in formatsUnstruct:
formats.append('ePub')
if 'pdf' in formatsUnstruct:
formats.append('PDF')
if 'fb2' in formatsUnstruct:
formats.append('FB2')
if 'rtf' in formatsUnstruct:
formats.append('RTF')
if 'txt' in formatsUnstruct:
formats.append('TXT')
if 'djvu' in formatsUnstruct:
formats.append('DjVu')
if 'doc' in formatsUnstruct:
formats.append('DOC')
return formats

View File

@ -5541,23 +5541,23 @@ msgstr "Книги с такими же тегами"
#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:20
msgid "Get books"
msgstr ""
msgstr "Загрузить книги"
#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:29
msgid "Search for ebooks"
msgstr ""
msgstr "Поиск книг..."
#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:30
msgid "Search for this author"
msgstr ""
msgstr "Поиск по автору"
#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:31
msgid "Search for this title"
msgstr ""
msgstr "Поиск по названию"
#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:32
msgid "Search for this book"
msgstr ""
msgstr "Поиск по книге"
#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:34
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:135
@ -5569,21 +5569,21 @@ msgstr "Магазины"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/chooser_dialog.py:18
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:285
msgid "Choose stores"
msgstr ""
msgstr "Выбрать магазины"
#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:83
#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:102
#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:111
msgid "Cannot search"
msgstr ""
msgstr "Поиск не может быть произведён"
#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:130
msgid ""
"Calibre helps you find the ebooks you want by searching the websites of "
"various commercial and public domain book sources for you."
msgstr ""
"Calibre помогает вам отыскать книги, которые вы хотите найти, предлагая вам "
"найденные веб-сайты различных коммерческих и публичных источников книг."
"Calibre поможет Вам найти книги, предлагая "
"веб-сайты различных коммерческих и публичных источников книг."
#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:134
msgid ""
@ -5591,6 +5591,8 @@ msgid ""
"are looking for, at the best price. You also get DRM status and other useful "
"information."
msgstr ""
"Используя встроенный поиск Вы можете легко найти магазин предлагающий выгодную цену "
"для интересующей Вас книги. Также Вы получите другу полезную инфрмацию"
#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:138
msgid ""
@ -5608,7 +5610,7 @@ msgstr "Показать снова данное сообщение"
#: /home/kovid/work/calibre/src/calibre/gui2/actions/store.py:149
msgid "About Get Books"
msgstr ""
msgstr "О 'Загрузить книги'"
#: /home/kovid/work/calibre/src/calibre/gui2/actions/tweak_epub.py:17
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/tweak_epub_ui.py:60
@ -5617,7 +5619,7 @@ msgstr "Tweak EPUB"
#: /home/kovid/work/calibre/src/calibre/gui2/actions/tweak_epub.py:18
msgid "Make small changes to ePub format books"
msgstr ""
msgstr "Внести небольшие изненения ePub в формат книги"
#: /home/kovid/work/calibre/src/calibre/gui2/actions/tweak_epub.py:19
msgid "T"
@ -5704,7 +5706,7 @@ msgstr "Не могу открыть папку"
#: /home/kovid/work/calibre/src/calibre/gui2/actions/view.py:220
msgid "This book no longer exists in your library"
msgstr ""
msgstr "Эта книга больше не находится в Вашей библиотеке"
#: /home/kovid/work/calibre/src/calibre/gui2/actions/view.py:227
#, python-format
@ -9167,11 +9169,11 @@ msgstr "&Показать пароль"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:122
msgid "Restart required"
msgstr ""
msgstr "Требуется перезапуск"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:123
msgid "You must restart Calibre before using this plugin!"
msgstr ""
msgstr "Для использования плагина Вам нужно перезапустить Calibre!"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:164
#, python-format
@ -9183,17 +9185,17 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:136
#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:111
msgid "All"
msgstr ""
msgstr "Всё"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:184
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:302
msgid "Installed"
msgstr ""
msgstr "Установленные"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:184
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:397
msgid "Not installed"
msgstr ""
msgstr "Не установленные"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:184
msgid "Update available"
@ -9201,7 +9203,7 @@ msgstr "Доступно обновление"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:302
msgid "Plugin Name"
msgstr ""
msgstr "Название плагина"
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/plugin_updater.py:302
#: /home/kovid/work/calibre/src/calibre/gui2/jobs.py:63
@ -13317,7 +13319,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/plugins_ui.py:114
msgid "&Load plugin from file"
msgstr ""
msgstr "Загрузить плагин из файла"
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template.py:33
msgid "Any custom field"
@ -13579,11 +13581,11 @@ msgstr "Сбой запуска контент-сервера"
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:106
msgid "Error log:"
msgstr "Лог ошибок:"
msgstr "Журнал ошибок:"
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:113
msgid "Access log:"
msgstr "Лог доступа:"
msgstr "Журнал доступа:"
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/server.py:128
msgid "You need to restart the server for changes to take effect"
@ -14053,7 +14055,7 @@ msgstr "Ничего"
#: /home/kovid/work/calibre/src/calibre/gui2/shortcuts.py:59
msgid "Press a key..."
msgstr ""
msgstr "Нажмите клавишу..."
#: /home/kovid/work/calibre/src/calibre/gui2/shortcuts.py:80
msgid "Already assigned"
@ -14108,19 +14110,19 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/basic_config_widget_ui.py:38
msgid "Added Tags:"
msgstr ""
msgstr "Добавленные тэги:"
#: /home/kovid/work/calibre/src/calibre/gui2/store/basic_config_widget_ui.py:39
msgid "Open store in external web browswer"
msgstr ""
msgstr "Открыть сайт магазина в интернет броузере"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/adv_search_builder_ui.py:219
msgid "&Name:"
msgstr ""
msgstr "&Название"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/adv_search_builder_ui.py:221
msgid "&Description:"
msgstr ""
msgstr "&Описание"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/adv_search_builder_ui.py:222
msgid "&Headquarters:"
@ -14140,7 +14142,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/adv_search_builder_ui.py:217
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/adv_search_builder_ui.py:220
msgid "true"
msgstr ""
msgstr "да"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/adv_search_builder_ui.py:229
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/adv_search_builder_ui.py:231
@ -14148,41 +14150,41 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/adv_search_builder_ui.py:218
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/adv_search_builder_ui.py:221
msgid "false"
msgstr ""
msgstr "нет"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/adv_search_builder_ui.py:232
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/adv_search_builder_ui.py:216
msgid "Affiliate:"
msgstr ""
msgstr "Партнёрство:"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/adv_search_builder_ui.py:235
msgid "Nam&e/Description ..."
msgstr ""
msgstr "Названи&е/Описание"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/chooser_widget_ui.py:78
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:132
#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:108
msgid "Query:"
msgstr ""
msgstr "Запрос:"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/chooser_widget_ui.py:81
msgid "Enable"
msgstr ""
msgstr "Включить"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/chooser_widget_ui.py:84
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:137
#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:112
msgid "Invert"
msgstr ""
msgstr "Инвертировать"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/models.py:21
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:37
msgid "Affiliate"
msgstr ""
msgstr "Партнерство"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/models.py:21
msgid "Enabled"
msgstr ""
msgstr "Включено"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/models.py:21
msgid "Headquarters"
@ -14190,7 +14192,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/models.py:21
msgid "No DRM"
msgstr ""
msgstr "Без DRM"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/models.py:129
msgid ""
@ -14205,13 +14207,14 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/models.py:136
msgid "This store only distributes ebooks without DRM."
msgstr ""
msgstr "Этот магазин распространяет электронные книги исключительно без DRM"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/models.py:138
msgid ""
"This store distributes ebooks with DRM. It may have some titles without DRM, "
"but you will need to check on a per title basis."
msgstr ""
msgstr "Этот магазин распространяет электронные книги с DRM. Возможно, некоторые издания"
" доступны без DRM, но для этого надо проверять каждую книгу в отдельности."
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/models.py:140
#, python-format
@ -14225,46 +14228,46 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:211
#, python-format
msgid "Buying from this store supports the calibre developer: %s."
msgstr ""
msgstr "Покупая в этом магазине Вы поддерживаете проект calibre и разработчика: %s."
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/models.py:145
#, python-format
msgid "This store distributes ebooks in the following formats: %s"
msgstr ""
msgstr "Магазин распространяет эл. книги в следующих фотрматах"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/chooser/results_view.py:47
msgid "Configure..."
msgstr ""
msgstr "Настроить..."
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:99
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:99
msgid "Time"
msgstr ""
msgstr "Время"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:100
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:100
msgid "Number of seconds to wait for a store to respond"
msgstr ""
msgstr "Время ожидания ответа магазина (в секундах)"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:101
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:101
msgid "Number of seconds to let a store process results"
msgstr ""
msgstr "Допустипое время обработки результата магазином (в секундах)"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:102
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:102
msgid "Display"
msgstr ""
msgstr "Показать"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:103
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:103
msgid "Maximum number of results to show per store"
msgstr ""
msgstr "Максимальное количество результатов для показа (по каждому магазину)"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:104
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:104
msgid "Open search result in system browser"
msgstr ""
msgstr "Показывать результаты поиска в системном интернет броузере"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search/search_widget_ui.py:105
msgid "Threads"
@ -14288,11 +14291,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:105
msgid "Performance"
msgstr ""
msgstr "Производительность"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:106
msgid "Number of simultaneous searches"
msgstr ""
msgstr "Количество одновременно выполняемых поисков"
#: /home/kovid/work/calibre/src/calibre/gui2/store/config/search_widget_ui.py:107
msgid "Number of simultaneous cache updates"
@ -14308,13 +14311,13 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/mobileread_store_dialog_ui.py:62
msgid "Search:"
msgstr ""
msgstr "Поиск:"
#: /home/kovid/work/calibre/src/calibre/gui2/store/mobileread_store_dialog_ui.py:63
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:142
#: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/store_dialog_ui.py:77
msgid "Books:"
msgstr ""
msgstr "Книги:"
#: /home/kovid/work/calibre/src/calibre/gui2/store/mobileread_store_dialog_ui.py:65
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:144
@ -14323,20 +14326,20 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/web_store_dialog_ui.py:63
#: /usr/src/qt-everywhere-opensource-src-4.7.2/src/gui/widgets/qdialogbuttonbox.cpp:661
msgid "Close"
msgstr ""
msgstr "Закрыть"
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/adv_search_builder_ui.py:212
msgid "&Price:"
msgstr ""
msgstr "&Цена:"
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/adv_search_builder_ui.py:219
msgid "Download:"
msgstr ""
msgstr "Скачать"
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/adv_search_builder_ui.py:222
#: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/adv_search_builder_ui.py:187
msgid "Titl&e/Author/Price ..."
msgstr ""
msgstr "Названи&е/Автор/Цена ..."
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:37
msgid "DRM"
@ -14344,11 +14347,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:37
msgid "Download"
msgstr ""
msgstr "Скачать"
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:37
msgid "Price"
msgstr ""
msgstr "Цена"
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:196
#, python-format
@ -14383,90 +14386,90 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/models.py:208
#, python-format
msgid "The following formats can be downloaded directly: %s."
msgstr ""
msgstr "Форматы доступные для непосредственного скачивания: %s."
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/results_view.py:41
msgid "Download..."
msgstr ""
msgstr "Скачать..."
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/results_view.py:45
msgid "Goto in store..."
msgstr ""
msgstr "Перейти в магазин..."
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:114
#, python-format
msgid "Buying from this store supports the calibre developer: %s</p>"
msgstr ""
msgstr "Покупая в этом магазине Вы поддерживаете проект calibre и разработчика: %s</p>"
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:276
msgid "Customize get books search"
msgstr ""
msgstr "Перенастроить под себя поиск книг для скачивания"
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:286
msgid "Configure search"
msgstr ""
msgstr "Настроить поиск"
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:336
msgid "Couldn't find any books matching your query."
msgstr "Ну удалось найти ни одной кники, соотвествующей вашему запросу."
msgstr "Не удалось найти ни одной книги, соотвествующей вашему запросу."
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search.py:350
msgid "Choose format to download to your library."
msgstr ""
msgstr "Выберите формат для скачивания в библиотеку"
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:131
#: /home/kovid/work/calibre/src/calibre/gui2/store/search_ui.py:107
msgid "Get Books"
msgstr ""
msgstr "Скачать книги"
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:140
msgid "Open a selected book in the system's web browser"
msgstr ""
msgstr "Показать выбранную книгу в системном интернет броузере"
#: /home/kovid/work/calibre/src/calibre/gui2/store/search/search_ui.py:141
msgid "Open in &external browser"
msgstr ""
msgstr "Показывать в системном интернет броузере"
#: /home/kovid/work/calibre/src/calibre/gui2/store/stores/ebooks_com_plugin.py:96
msgid "Not Available"
msgstr ""
msgstr "Недоступно"
#: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/adv_search_builder_ui.py:179
msgid ""
"See the <a href=\"http://calibre-ebook.com/user_manual/gui.html#the-search-"
"interface\">User Manual</a> for more help"
msgstr ""
"Смотри <a href=\"http://calibre-ebook.com/user_manual/gui.html#the-search-"
"interface\">Пользовательский мануал</a> для помощи"
"Смотрите <a href=\"http://calibre-ebook.com/user_manual/gui.html#the-search-"
"interface\">Руководство пользователя</a> для помощи"
#: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/cache_progress_dialog_ui.py:51
msgid "Updating book cache"
msgstr ""
msgstr "Обноволяется кэш книг"
#: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/cache_update_thread.py:42
msgid "Checking last download date."
msgstr ""
msgstr "Проверяется врема последнего скачивания"
#: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/cache_update_thread.py:48
msgid "Downloading book list from MobileRead."
msgstr ""
msgstr "Загружается список книг с MobileRead."
#: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/cache_update_thread.py:61
msgid "Processing books."
msgstr ""
msgstr "Книги обрабатываются"
#: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/cache_update_thread.py:71
#, python-format
msgid "%(num)s of %(tot)s books processed."
msgstr ""
msgstr "обработано %(num)s из %(tot)."
#: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/mobileread_plugin.py:62
msgid "Updating MobileRead book cache..."
msgstr ""
msgstr "Обноволяется кэщ MobileRead книг..."
#: /home/kovid/work/calibre/src/calibre/gui2/store/stores/mobileread/store_dialog_ui.py:74
msgid "&Query:"
msgstr ""
msgstr "&Запрос:"
#: /home/kovid/work/calibre/src/calibre/gui2/store/web_control.py:73
msgid ""
@ -14480,15 +14483,15 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/store/web_control.py:86
msgid "File is not a supported ebook type. Save to disk?"
msgstr ""
msgstr "Файл содержит неподдерживаемый формат эл. книги. Сохранить на диске?"
#: /home/kovid/work/calibre/src/calibre/gui2/store/web_store_dialog_ui.py:59
msgid "Home"
msgstr ""
msgstr "Главная страница"
#: /home/kovid/work/calibre/src/calibre/gui2/store/web_store_dialog_ui.py:60
msgid "Reload"
msgstr ""
msgstr "Перегрузить"
#: /home/kovid/work/calibre/src/calibre/gui2/store/web_store_dialog_ui.py:61
msgid "%p%"
@ -14502,22 +14505,24 @@ msgstr ""
msgid ""
"Changing the authors for several books can take a while. Are you sure?"
msgstr ""
"Изменить автора нескольких книг займёт некоторое время. Вы согласны"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:729
msgid ""
"Changing the metadata for that many books can take a while. Are you sure?"
msgstr ""
"Изменить мета-данные нескольких книг займёт некоторое время. Вы согласны"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:816
#: /home/kovid/work/calibre/src/calibre/library/database2.py:449
msgid "Searches"
msgstr ""
msgstr "Поиски"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:881
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:901
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:910
msgid "Rename user category"
msgstr ""
msgstr "Переименовать пользовательскую категорию"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:882
msgid "You cannot use periods in the name when renaming user categories"
@ -14540,30 +14545,30 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:48
msgid "Manage Authors"
msgstr ""
msgstr "Упорядочнить авторов"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:50
msgid "Manage Series"
msgstr ""
msgstr "Упорядочнить серии"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:52
msgid "Manage Publishers"
msgstr ""
msgstr "Упорядочнить издателей"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:54
msgid "Manage Tags"
msgstr ""
msgstr "Упорядочнить тэги"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:56
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:465
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:469
msgid "Manage User Categories"
msgstr "Управление пользовательскими категориями"
msgstr "Упорядочнить пользовательские категории"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:58
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:457
msgid "Manage Saved Searches"
msgstr "Управление сохраненными поисками"
msgstr "Упорядочнить сохраненные поиски"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:66
msgid "Invalid search restriction"
@ -14580,17 +14585,17 @@ msgstr "Новая категория"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:134
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:137
msgid "Delete user category"
msgstr ""
msgstr "Удалить пользовательскую категорию"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:135
#, python-format
msgid "%s is not a user category"
msgstr ""
msgstr "%s не является пользовательской категорией"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:138
#, python-format
msgid "%s contains items. Do you really want to delete it?"
msgstr ""
msgstr "%s содержит элементы. Вы действительно хотете её удалить?"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:159
msgid "Remove category"
@ -14599,16 +14604,16 @@ msgstr "Удалить категорию"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:160
#, python-format
msgid "User category %s does not exist"
msgstr ""
msgstr "Пользовательская категория %s не существует"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:179
msgid "Add to user category"
msgstr ""
msgstr "Добавить в пользовательские категории"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:180
#, python-format
msgid "A user category %s does not exist"
msgstr ""
msgstr "Пользовательская категория %s не существует"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/ui.py:305
msgid "Find item in tag browser"
@ -14701,7 +14706,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:359
#, python-format
msgid "Add %s to user category"
msgstr ""
msgstr "Добавить %s в пользовательские категории"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:372
#, python-format
@ -14711,7 +14716,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:382
#, python-format
msgid "Delete search %s"
msgstr ""
msgstr "Удалить поиск %s"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:387
#, python-format
@ -14721,27 +14726,27 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:394
#, python-format
msgid "Search for %s"
msgstr ""
msgstr "Искать %s"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:399
#, python-format
msgid "Search for everything but %s"
msgstr ""
msgstr "Искать всё кроме %s"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:411
#, python-format
msgid "Add sub-category to %s"
msgstr ""
msgstr "Добавить подкатегорию в %s"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:415
#, python-format
msgid "Delete user category %s"
msgstr ""
msgstr "Удалить пользовательскую категорию %s"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:420
#, python-format
msgid "Hide category %s"
msgstr ""
msgstr "Скрыть категорию %s"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:424
msgid "Show category"
@ -14750,12 +14755,12 @@ msgstr "Показать категорию"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:434
#, python-format
msgid "Search for books in category %s"
msgstr ""
msgstr "Искать книги в категории %s"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:440
#, python-format
msgid "Search for books not in category %s"
msgstr ""
msgstr "Искать книги НЕ в категории %s"
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:449
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/view.py:454
@ -14837,7 +14842,7 @@ msgstr "Извлечь подключенное устройство"
#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:347
msgid "Debug mode"
msgstr ""
msgstr "Резим отладки"
#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:348
#, python-format
@ -14875,7 +14880,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:630
msgid "Active jobs"
msgstr ""
msgstr "Активные задания"
#: /home/kovid/work/calibre/src/calibre/gui2/ui.py:698
msgid ""
@ -14898,11 +14903,11 @@ msgstr "Доступно обновление!"
#: /home/kovid/work/calibre/src/calibre/gui2/update.py:84
msgid "Show this notification for future updates"
msgstr ""
msgstr "Показвать сообщение о доступности новой версии (обнивления)"
#: /home/kovid/work/calibre/src/calibre/gui2/update.py:89
msgid "&Get update"
msgstr ""
msgstr "&Скачать обнивление"
#: /home/kovid/work/calibre/src/calibre/gui2/update.py:93
msgid "Update &plugins"
@ -14929,11 +14934,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/update.py:187
#, python-format
msgid "There are %d plugin updates available"
msgstr ""
msgstr "Доступны обновления для %d плагинов"
#: /home/kovid/work/calibre/src/calibre/gui2/update.py:191
msgid "Install and configure user plugins"
msgstr ""
msgstr "Установка и настройка пользовательских плагинов"
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/bookmarkmanager.py:43
msgid "Edit bookmark"