mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Implement exporting of reports to csv files
This commit is contained in:
parent
11f9e0f31a
commit
abdcbcdd82
@ -11,6 +11,8 @@ from future_builtins import map
|
|||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from csv import writer as csv_writer
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
import regex
|
import regex
|
||||||
from PyQt5.Qt import (
|
from PyQt5.Qt import (
|
||||||
@ -21,7 +23,7 @@ from PyQt5.Qt import (
|
|||||||
|
|
||||||
from calibre import human_readable, fit_image
|
from calibre import human_readable, fit_image
|
||||||
from calibre.ebooks.oeb.polish.report import gather_data
|
from calibre.ebooks.oeb.polish.report import gather_data
|
||||||
from calibre.gui2 import error_dialog, question_dialog
|
from calibre.gui2 import error_dialog, question_dialog, choose_save_file
|
||||||
from calibre.gui2.tweak_book import current_container, tprefs, dictionaries
|
from calibre.gui2.tweak_book import current_container, tprefs, dictionaries
|
||||||
from calibre.gui2.tweak_book.widgets import Dialog
|
from calibre.gui2.tweak_book.widgets import Dialog
|
||||||
from calibre.gui2.progress_indicator import ProgressIndicator
|
from calibre.gui2.progress_indicator import ProgressIndicator
|
||||||
@ -167,6 +169,17 @@ class FilesView(QTableView):
|
|||||||
self.customize_context_menu(m, locations, self.current_location)
|
self.customize_context_menu(m, locations, self.current_location)
|
||||||
if len(m.actions()) > 0:
|
if len(m.actions()) > 0:
|
||||||
m.exec_(pos)
|
m.exec_(pos)
|
||||||
|
|
||||||
|
def to_csv(self):
|
||||||
|
buf = BytesIO()
|
||||||
|
w = csv_writer(buf)
|
||||||
|
w.writerow(self.proxy.sourceModel().COLUMN_HEADERS)
|
||||||
|
cols = self.proxy.columnCount()
|
||||||
|
for r in xrange(self.proxy.rowCount()):
|
||||||
|
items = [self.proxy.index(r, c).data(Qt.DisplayRole) for c in xrange(cols)]
|
||||||
|
w.writerow(items)
|
||||||
|
return buf.getvalue()
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
# Files {{{
|
# Files {{{
|
||||||
@ -229,6 +242,7 @@ class FilesWidget(QWidget):
|
|||||||
e.setPlaceholderText(_('Filter'))
|
e.setPlaceholderText(_('Filter'))
|
||||||
self.model = m = FilesModel(self)
|
self.model = m = FilesModel(self)
|
||||||
self.files = f = FilesView(m, self)
|
self.files = f = FilesView(m, self)
|
||||||
|
self.to_csv = f.to_csv
|
||||||
f.delete_requested.connect(self.delete_requested)
|
f.delete_requested.connect(self.delete_requested)
|
||||||
f.double_clicked.connect(self.double_clicked)
|
f.double_clicked.connect(self.double_clicked)
|
||||||
e.textChanged.connect(f.proxy.filter_text)
|
e.textChanged.connect(f.proxy.filter_text)
|
||||||
@ -397,6 +411,7 @@ class ImagesWidget(QWidget):
|
|||||||
e.setPlaceholderText(_('Filter'))
|
e.setPlaceholderText(_('Filter'))
|
||||||
self.model = m = ImagesModel(self)
|
self.model = m = ImagesModel(self)
|
||||||
self.files = f = FilesView(m, self)
|
self.files = f = FilesView(m, self)
|
||||||
|
self.to_csv = f.to_csv
|
||||||
f.customize_context_menu = self.customize_context_menu
|
f.customize_context_menu = self.customize_context_menu
|
||||||
f.delete_requested.connect(self.delete_requested)
|
f.delete_requested.connect(self.delete_requested)
|
||||||
f.horizontalHeader().sortIndicatorChanged.connect(self.resize_to_contents)
|
f.horizontalHeader().sortIndicatorChanged.connect(self.resize_to_contents)
|
||||||
@ -492,6 +507,7 @@ class WordsWidget(QWidget):
|
|||||||
e.setPlaceholderText(_('Filter'))
|
e.setPlaceholderText(_('Filter'))
|
||||||
self.model = m = WordsModel(self)
|
self.model = m = WordsModel(self)
|
||||||
self.words = f = FilesView(m, self)
|
self.words = f = FilesView(m, self)
|
||||||
|
self.to_csv = f.to_csv
|
||||||
f.DELETE_POSSIBLE = False
|
f.DELETE_POSSIBLE = False
|
||||||
f.double_clicked.connect(self.double_clicked)
|
f.double_clicked.connect(self.double_clicked)
|
||||||
e.textChanged.connect(f.proxy.filter_text)
|
e.textChanged.connect(f.proxy.filter_text)
|
||||||
@ -573,6 +589,7 @@ class CharsWidget(QWidget):
|
|||||||
e.setPlaceholderText(_('Filter'))
|
e.setPlaceholderText(_('Filter'))
|
||||||
self.model = m = CharsModel(self)
|
self.model = m = CharsModel(self)
|
||||||
self.chars = f = FilesView(m, self)
|
self.chars = f = FilesView(m, self)
|
||||||
|
self.to_csv = f.to_csv
|
||||||
f.DELETE_POSSIBLE = False
|
f.DELETE_POSSIBLE = False
|
||||||
f.double_clicked.connect(self.double_clicked)
|
f.double_clicked.connect(self.double_clicked)
|
||||||
e.textChanged.connect(f.proxy.filter_text)
|
e.textChanged.connect(f.proxy.filter_text)
|
||||||
@ -690,6 +707,19 @@ class ReportsWidget(QWidget):
|
|||||||
for i in xrange(self.stack.count()):
|
for i in xrange(self.stack.count()):
|
||||||
self.stack.widget(i).save()
|
self.stack.widget(i).save()
|
||||||
|
|
||||||
|
def to_csv(self):
|
||||||
|
w = self.stack.currentWidget()
|
||||||
|
category = self.reports.currentItem().data(Qt.DisplayRole)
|
||||||
|
if not hasattr(w, 'to_csv'):
|
||||||
|
return error_dialog(self, _('Not supported'), _(
|
||||||
|
'Export of %s data is not supported') % category, show=True)
|
||||||
|
data = w.to_csv()
|
||||||
|
fname = choose_save_file(self, 'report-csv-export', _('Choose a filename for the data'), filters=[
|
||||||
|
(_('CSV files'), ['csv'])], all_files=False, initial_filename='%s.csv' % category)
|
||||||
|
if fname:
|
||||||
|
with open(fname, 'wb') as f:
|
||||||
|
f.write(data)
|
||||||
|
|
||||||
class Reports(Dialog):
|
class Reports(Dialog):
|
||||||
|
|
||||||
data_gathered = pyqtSignal(object, object)
|
data_gathered = pyqtSignal(object, object)
|
||||||
@ -723,7 +753,11 @@ class Reports(Dialog):
|
|||||||
self.bb.setStandardButtons(self.bb.Close)
|
self.bb.setStandardButtons(self.bb.Close)
|
||||||
self.refresh_button = b = self.bb.addButton(_('&Refresh'), self.bb.ActionRole)
|
self.refresh_button = b = self.bb.addButton(_('&Refresh'), self.bb.ActionRole)
|
||||||
b.clicked.connect(self.refresh)
|
b.clicked.connect(self.refresh)
|
||||||
b.setIcon(QIcon(I('view-refresh')))
|
b.setIcon(QIcon(I('view-refresh.png')))
|
||||||
|
self.save_button = b = self.bb.addButton(_('&Save'), self.bb.ActionRole)
|
||||||
|
b.clicked.connect(self.reports.to_csv)
|
||||||
|
b.setIcon(QIcon(I('save.png')))
|
||||||
|
b.setToolTip(_('Export the currently shown report as a CSV file'))
|
||||||
|
|
||||||
def sizeHint(self):
|
def sizeHint(self):
|
||||||
return QSize(950, 600)
|
return QSize(950, 600)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user