mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Bibtex export plugin first implementation
This commit is contained in:
parent
1d1a19f4d0
commit
4fb3a73d85
@ -467,12 +467,12 @@ from calibre.devices.kobo.driver import KOBO
|
|||||||
from calibre.ebooks.metadata.fetch import GoogleBooks, ISBNDB, Amazon, \
|
from calibre.ebooks.metadata.fetch import GoogleBooks, ISBNDB, Amazon, \
|
||||||
LibraryThing
|
LibraryThing
|
||||||
from calibre.ebooks.metadata.douban import DoubanBooks
|
from calibre.ebooks.metadata.douban import DoubanBooks
|
||||||
from calibre.library.catalog import CSV_XML, EPUB_MOBI
|
from calibre.library.catalog import CSV_XML, EPUB_MOBI, BIBTEX
|
||||||
from calibre.ebooks.epub.fix.unmanifested import Unmanifested
|
from calibre.ebooks.epub.fix.unmanifested import Unmanifested
|
||||||
from calibre.ebooks.epub.fix.epubcheck import Epubcheck
|
from calibre.ebooks.epub.fix.epubcheck import Epubcheck
|
||||||
|
|
||||||
plugins = [HTML2ZIP, PML2PMLZ, ArchiveExtract, GoogleBooks, ISBNDB, Amazon,
|
plugins = [HTML2ZIP, PML2PMLZ, ArchiveExtract, GoogleBooks, ISBNDB, Amazon,
|
||||||
LibraryThing, DoubanBooks, CSV_XML, EPUB_MOBI, Unmanifested, Epubcheck]
|
LibraryThing, DoubanBooks, CSV_XML, EPUB_MOBI, BIBTEX, Unmanifested, Epubcheck]
|
||||||
plugins += [
|
plugins += [
|
||||||
ComicInput,
|
ComicInput,
|
||||||
EPUBInput,
|
EPUBInput,
|
||||||
|
52
src/calibre/gui2/catalog/catalog_bibtex.py
Normal file
52
src/calibre/gui2/catalog/catalog_bibtex.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
|
from __future__ import with_statement
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
|
|
||||||
|
from calibre.gui2 import gprefs
|
||||||
|
from calibre.gui2.catalog.catalog_bibtex_ui import Ui_Form
|
||||||
|
from PyQt4.Qt import QWidget, QListWidgetItem
|
||||||
|
|
||||||
|
class PluginWidget(QWidget, Ui_Form):
|
||||||
|
|
||||||
|
TITLE = _('BibTeX Options')
|
||||||
|
HELP = _('Options specific to')+' BibTeX '+_('output')
|
||||||
|
sync_enabled = False
|
||||||
|
formats = set(['bib'])
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
QWidget.__init__(self, parent)
|
||||||
|
self.setupUi(self)
|
||||||
|
from calibre.library.catalog import FIELDS
|
||||||
|
self.all_fields = []
|
||||||
|
for x in FIELDS:
|
||||||
|
if x != 'all':
|
||||||
|
self.all_fields.append(x)
|
||||||
|
QListWidgetItem(x, self.db_fields)
|
||||||
|
|
||||||
|
def initialize(self, name):
|
||||||
|
self.name = name
|
||||||
|
fields = gprefs.get(name+'_db_fields', self.all_fields)
|
||||||
|
# Restore the activated fields from last use
|
||||||
|
for x in xrange(self.db_fields.count()):
|
||||||
|
item = self.db_fields.item(x)
|
||||||
|
item.setSelected(unicode(item.text()) in fields)
|
||||||
|
|
||||||
|
def options(self):
|
||||||
|
# Save the currently activated fields
|
||||||
|
fields = []
|
||||||
|
for x in xrange(self.db_fields.count()):
|
||||||
|
item = self.db_fields.item(x)
|
||||||
|
if item.isSelected():
|
||||||
|
fields.append(unicode(item.text()))
|
||||||
|
gprefs.set(self.name+'_db_fields', fields)
|
||||||
|
|
||||||
|
# Return a dictionary with current options for this widget
|
||||||
|
if len(self.db_fields.selectedItems()):
|
||||||
|
return {'fields':[unicode(item.text()) for item in self.db_fields.selectedItems()]}
|
||||||
|
else:
|
||||||
|
return {'fields':['all']}
|
47
src/calibre/gui2/catalog/catalog_bibtex.ui
Normal file
47
src/calibre/gui2/catalog/catalog_bibtex.ui
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>Form</class>
|
||||||
|
<widget class="QWidget" name="Form">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>579</width>
|
||||||
|
<height>411</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Fields to include in output:</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QListWidget" name="db_fields">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string extracomment="Select all fields to be exported"/>
|
||||||
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::MultiSelection</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
2593
src/calibre/library/bibtex.py
Normal file
2593
src/calibre/library/bibtex.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2010, Greg Riker <griker at hotmail.com>'
|
__copyright__ = '2010, Greg Riker <griker at hotmail.com>'
|
||||||
|
|
||||||
import datetime, htmlentitydefs, os, re, shutil
|
import datetime, htmlentitydefs, os, re, shutil, codecs
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
@ -9,6 +9,7 @@ from copy import deepcopy
|
|||||||
from xml.sax.saxutils import escape
|
from xml.sax.saxutils import escape
|
||||||
|
|
||||||
from calibre import filesystem_encoding, prints, prepare_string_for_xml, strftime
|
from calibre import filesystem_encoding, prints, prepare_string_for_xml, strftime
|
||||||
|
from calibre.constants import preferred_encoding
|
||||||
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
|
||||||
@ -16,11 +17,14 @@ from calibre.ptempfile import PersistentTemporaryDirectory
|
|||||||
from calibre.utils.date import isoformat, now as nowf
|
from calibre.utils.date import isoformat, now as nowf
|
||||||
from calibre.utils.logging import default_log as log
|
from calibre.utils.logging import default_log as log
|
||||||
|
|
||||||
|
#Bibtex functions
|
||||||
|
from calibre.library.bibtex import create_bibtex_entry, utf8ToBibtex
|
||||||
|
|
||||||
FIELDS = ['all', 'author_sort', 'authors', 'comments',
|
FIELDS = ['all', 'author_sort', 'authors', 'comments',
|
||||||
'cover', 'formats', 'id', 'isbn', 'pubdate', 'publisher', 'rating',
|
'cover', 'formats', 'id', 'isbn', 'pubdate', 'publisher', 'rating',
|
||||||
'series_index', 'series', 'size', 'tags', 'timestamp', 'title',
|
'series_index', 'series', 'size', 'tags', 'timestamp', 'title',
|
||||||
'uuid']
|
'uuid']
|
||||||
|
|
||||||
class CSV_XML(CatalogPlugin):
|
class CSV_XML(CatalogPlugin):
|
||||||
'CSV/XML catalog generator'
|
'CSV/XML catalog generator'
|
||||||
|
|
||||||
@ -181,6 +185,89 @@ class CSV_XML(CatalogPlugin):
|
|||||||
f.write(etree.tostring(root, encoding='utf-8',
|
f.write(etree.tostring(root, encoding='utf-8',
|
||||||
xml_declaration=True, pretty_print=True))
|
xml_declaration=True, pretty_print=True))
|
||||||
|
|
||||||
|
class BIBTEX(CatalogPlugin):
|
||||||
|
'BIBTEX catalog generator'
|
||||||
|
|
||||||
|
Option = namedtuple('Option', 'option, default, dest, action, help')
|
||||||
|
|
||||||
|
name = 'Catalog_BIBTEX'
|
||||||
|
description = 'BIBTEX catalog generator'
|
||||||
|
supported_platforms = ['windows', 'osx', 'linux']
|
||||||
|
author = 'Sengian'
|
||||||
|
version = (1, 0, 0)
|
||||||
|
file_types = set(['bib'])
|
||||||
|
|
||||||
|
cli_options = [
|
||||||
|
Option('--fields',
|
||||||
|
default = 'all',
|
||||||
|
dest = 'fields',
|
||||||
|
action = None,
|
||||||
|
help = _('The fields to output when cataloging books in the '
|
||||||
|
'database. Should be a comma-separated list of fields.\n'
|
||||||
|
'Available fields: %s.\n'
|
||||||
|
"Default: '%%default'\n"
|
||||||
|
"Applies to: BIBTEX output format")%', '.join(FIELDS)),
|
||||||
|
|
||||||
|
Option('--entry-type',
|
||||||
|
default = 'book',
|
||||||
|
dest = 'entry_type',
|
||||||
|
action = None,
|
||||||
|
help = _('Entry type for BIBTEX catalog.\n'
|
||||||
|
'Available types: book, misc, mixed.\n'
|
||||||
|
"Default: '%default'\n"
|
||||||
|
"Applies to: BIBTEX output format"))]
|
||||||
|
|
||||||
|
def run(self, path_to_output, opts, db, notification=DummyReporter()):
|
||||||
|
self.fmt = path_to_output.rpartition('.')[2]
|
||||||
|
self.notification = notification
|
||||||
|
|
||||||
|
if opts.verbose:
|
||||||
|
opts_dict = vars(opts)
|
||||||
|
log("%s(): Generating %s" % (self.name,self.fmt))
|
||||||
|
if opts_dict['search_text']:
|
||||||
|
log(" --search='%s'" % opts_dict['search_text'])
|
||||||
|
|
||||||
|
if opts_dict['ids']:
|
||||||
|
log(" Book count: %d" % len(opts_dict['ids']))
|
||||||
|
if opts_dict['search_text']:
|
||||||
|
log(" (--search ignored when a subset of the database is specified)")
|
||||||
|
|
||||||
|
if opts_dict['fields']:
|
||||||
|
if opts_dict['fields'] == 'all':
|
||||||
|
log(" Fields: %s" % ', '.join(FIELDS[1:]))
|
||||||
|
else:
|
||||||
|
log(" Fields: %s" % opts_dict['fields'])
|
||||||
|
|
||||||
|
|
||||||
|
# If a list of ids are provided, don't use search_text
|
||||||
|
if opts.ids:
|
||||||
|
opts.search_text = None
|
||||||
|
|
||||||
|
data = self.search_sort_db(db, opts)
|
||||||
|
|
||||||
|
if not len(data):
|
||||||
|
log.error("\nNo matching database entries for search criteria '%s'" % opts.search_text)
|
||||||
|
|
||||||
|
# Get the requested output fields as a list
|
||||||
|
fields = self.get_output_fields(opts)
|
||||||
|
|
||||||
|
if not len(data):
|
||||||
|
log.error("\nNo matching database entries for search criteria '%s'" % opts.search_text)
|
||||||
|
|
||||||
|
#Open output and write entries
|
||||||
|
outfile = codecs.open(path_to_output, 'w', 'ascii')
|
||||||
|
|
||||||
|
#File header
|
||||||
|
nb_entries = len(vars(opts)['ids'])
|
||||||
|
outfile.write(u'%%%Calibre catalog\n%%%{0} entries in catalog\n\n'.format(nb_entries))
|
||||||
|
outfile.write(u'@preamble{"This catalog of %d entries was generated by calibre on %s"}\n\n'
|
||||||
|
% (nb_entries, nowf().strftime("%A, %d. %B %Y %H:%M").decode(preferred_encoding)))
|
||||||
|
|
||||||
|
#Entries
|
||||||
|
for entry in data:
|
||||||
|
outfile.write(create_bibtex_entry(entry, fields))
|
||||||
|
|
||||||
|
outfile.close()
|
||||||
|
|
||||||
class EPUB_MOBI(CatalogPlugin):
|
class EPUB_MOBI(CatalogPlugin):
|
||||||
'ePub catalog generator'
|
'ePub catalog generator'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user