mirror of
https://github.com/JimmXinu/FanFicFare.git
synced 2026-01-06 16:17:56 +01:00
Customizable, dropdown Reject Reasons. Plugin only.
This commit is contained in:
parent
2e331c8d78
commit
85d40e0399
3 changed files with 128 additions and 58 deletions
|
|
@ -10,8 +10,10 @@ __docformat__ = 'restructuredtext en'
|
|||
import traceback, copy, threading
|
||||
from collections import OrderedDict
|
||||
|
||||
from PyQt4.Qt import (QDialog, QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QFont, QWidget,
|
||||
QTextEdit, QComboBox, QCheckBox, QPushButton, QTabWidget, QVariant, QScrollArea)
|
||||
from PyQt4.Qt import (QDialog, QWidget, QVBoxLayout, QHBoxLayout, QLabel,
|
||||
QLineEdit, QFont, QWidget, QTextEdit, QComboBox,
|
||||
QCheckBox, QPushButton, QTabWidget, QVariant, QScrollArea,
|
||||
QDialogButtonBox )
|
||||
|
||||
from calibre.gui2 import dynamic, info_dialog
|
||||
from calibre.utils.config import JSONConfig
|
||||
|
|
@ -35,6 +37,9 @@ PREFS_KEY_SETTINGS = 'settings'
|
|||
default_prefs = {}
|
||||
default_prefs['personal.ini'] = get_resources('plugin-example.ini')
|
||||
default_prefs['rejecturls'] = ''
|
||||
default_prefs['rejectreasons'] = '''Sucked
|
||||
Boring
|
||||
Dup from another site'''
|
||||
|
||||
default_prefs['updatemeta'] = True
|
||||
default_prefs['updatecover'] = False
|
||||
|
|
@ -199,6 +204,9 @@ class RejectURLList:
|
|||
def get_list(self):
|
||||
return copy.deepcopy(self._get_listcache())
|
||||
|
||||
def get_reject_reasons(self):
|
||||
return self.prefs['rejectreasons'].splitlines()
|
||||
|
||||
rejecturllist = RejectURLList(prefs)
|
||||
|
||||
class ConfigWidget(QWidget):
|
||||
|
|
@ -462,10 +470,19 @@ class BasicTab(QWidget):
|
|||
|
||||
self.l.addSpacing(10)
|
||||
|
||||
self.rejectlist = QPushButton('View Reject URL List', self)
|
||||
self.rejectlist.setToolTip("View list of URLs FFDL will automatically Reject.")
|
||||
horz = QHBoxLayout()
|
||||
|
||||
self.rejectlist = QPushButton('Edit Reject URL List', self)
|
||||
self.rejectlist.setToolTip("Edit list of URLs FFDL will automatically Reject.")
|
||||
self.rejectlist.clicked.connect(self.show_rejectlist)
|
||||
self.l.addWidget(self.rejectlist)
|
||||
horz.addWidget(self.rejectlist)
|
||||
|
||||
self.reject_reasons = QPushButton('Edit Reject Reasons List', self)
|
||||
self.reject_reasons.setToolTip("Customize the Reasons presented when Rejecting URLs")
|
||||
self.reject_reasons.clicked.connect(self.show_reject_reasons)
|
||||
horz.addWidget(self.reject_reasons)
|
||||
|
||||
self.l.addLayout(horz)
|
||||
|
||||
self.l.insertStretch(-1)
|
||||
|
||||
|
|
@ -486,10 +503,11 @@ class BasicTab(QWidget):
|
|||
def show_rejectlist(self):
|
||||
rejectlist = []
|
||||
for (url,note) in rejecturllist.get_list().items():
|
||||
rejectlist.append((None,url,note))
|
||||
rejectlist.append((None,url,note,note))
|
||||
|
||||
d = RejectListDialog(self,
|
||||
rejectlist,
|
||||
rejectreasons=rejecturllist.get_reject_reasons(),
|
||||
header="Edit Reject URLs List",
|
||||
show_delete=False)
|
||||
d.exec_()
|
||||
|
|
@ -503,6 +521,40 @@ class BasicTab(QWidget):
|
|||
|
||||
rejecturllist.add(rejectlist,clear=True)
|
||||
|
||||
def show_reject_reasons(self):
|
||||
print("rejectreasons:%s"%prefs['rejectreasons'])
|
||||
d = RejectReasonsDialog(self.windowIcon(),prefs['rejectreasons'],self)
|
||||
d.exec_()
|
||||
if d.result() == d.Accepted:
|
||||
prefs['rejectreasons'] = unicode(d.reasons.toPlainText())
|
||||
print("rejectreasons:%s"%prefs['rejectreasons'])
|
||||
|
||||
|
||||
class RejectReasonsDialog(QDialog):
|
||||
|
||||
def __init__(self, icon, text, parent=None):
|
||||
QDialog.__init__(self, parent)
|
||||
self.resize(600, 500)
|
||||
self.l = QVBoxLayout()
|
||||
self.setLayout(self.l)
|
||||
self.label = QLabel("Customize Reject List Reasons")
|
||||
tooltip="Customize the Reasons presented when Rejecting URLs"
|
||||
self.label.setToolTip(tooltip)
|
||||
self.setWindowTitle(_('Reject Reasons'))
|
||||
self.setWindowIcon(icon)
|
||||
self.l.addWidget(self.label)
|
||||
|
||||
self.reasons = QTextEdit(self)
|
||||
self.reasons.setToolTip(tooltip)
|
||||
self.reasons.setLineWrapMode(QTextEdit.NoWrap)
|
||||
self.reasons.setText(text)
|
||||
self.l.addWidget(self.reasons)
|
||||
|
||||
button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
||||
button_box.accepted.connect(self.accept)
|
||||
button_box.rejected.connect(self.reject)
|
||||
self.l.addWidget(button_box)
|
||||
|
||||
class PersonalIniTab(QWidget):
|
||||
|
||||
def __init__(self, parent_dialog, plugin_action):
|
||||
|
|
@ -542,34 +594,6 @@ class PersonalIniTab(QWidget):
|
|||
def show_defaults(self):
|
||||
text = get_resources('plugin-defaults.ini')
|
||||
ShowDefaultsIniDialog(self.windowIcon(),text,self).exec_()
|
||||
|
||||
# class RejectUrlsTab(QWidget):
|
||||
|
||||
# def __init__(self, parent_dialog, plugin_action):
|
||||
# self.parent_dialog = parent_dialog
|
||||
# self.plugin_action = plugin_action
|
||||
# QWidget.__init__(self)
|
||||
|
||||
# self.l = QVBoxLayout()
|
||||
# self.setLayout(self.l)
|
||||
|
||||
# label = QLabel("List of story URLs you've previously rejected followed by an optional note. FFDL will stop and ask you if try to download a story on your reject list. The system will put title, author and why you rejected it when added from the FFDL 'Reject Story' option.")
|
||||
# label.setWordWrap(True)
|
||||
# self.l.addWidget(label)
|
||||
# self.l.addSpacing(5)
|
||||
|
||||
# self.label = QLabel('Rejected URLs: (URL,Notes)')
|
||||
# self.l.addWidget(self.label)
|
||||
|
||||
# self.rejecturls = QTextEdit(self)
|
||||
# try:
|
||||
# self.rejecturls.setFont(QFont("Courier",
|
||||
# self.plugin_action.gui.font().pointSize()+1));
|
||||
# except Exception as e:
|
||||
# print("Couldn't get font: %s"%e)
|
||||
# self.rejecturls.setLineWrapMode(QTextEdit.NoWrap)
|
||||
# self.rejecturls.setText(prefs['rejecturls'])
|
||||
# self.l.addWidget(self.rejecturls)
|
||||
|
||||
class ShowDefaultsIniDialog(QDialog):
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ __copyright__ = '2011, Jim Miller'
|
|||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import traceback
|
||||
from functools import partial
|
||||
|
||||
from PyQt4 import QtGui
|
||||
from PyQt4.Qt import (QDialog, QTableWidget, QMessageBox, QVBoxLayout, QHBoxLayout,
|
||||
|
|
@ -19,6 +20,7 @@ from PyQt4.Qt import (QDialog, QTableWidget, QMessageBox, QVBoxLayout, QHBoxLayo
|
|||
|
||||
from calibre.gui2 import error_dialog, warning_dialog, question_dialog, info_dialog
|
||||
from calibre.gui2.dialogs.confirm_delete import confirm
|
||||
from calibre.gui2.complete2 import EditWithComplete
|
||||
|
||||
from calibre import confirm_config_name
|
||||
from calibre.gui2 import dynamic
|
||||
|
|
@ -717,9 +719,10 @@ class StoryListTableWidget(QTableWidget):
|
|||
|
||||
class RejectListTableWidget(QTableWidget):
|
||||
|
||||
def __init__(self, parent):
|
||||
def __init__(self, parent,rejectreasons=[]):
|
||||
QTableWidget.__init__(self, parent)
|
||||
self.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||
self.rejectreasons = rejectreasons
|
||||
|
||||
def on_headersection_clicked(self):
|
||||
self.setSortingEnabled(True)
|
||||
|
|
@ -755,22 +758,58 @@ class RejectListTableWidget(QTableWidget):
|
|||
|
||||
def populate_table_row(self, row, rejectrow):
|
||||
|
||||
(bookid,url,note) = rejectrow
|
||||
(bookid,url,titleauth,oldrejnote) = rejectrow
|
||||
if oldrejnote:
|
||||
noteprefix = note = oldrejnote
|
||||
# incase the existing note ends with one of the known reasons.
|
||||
for reason in self.rejectreasons:
|
||||
if noteprefix.endswith(' - '+reason):
|
||||
noteprefix = noteprefix[:-len(' - '+reason)]
|
||||
break
|
||||
else:
|
||||
noteprefix = note = titleauth
|
||||
|
||||
url_cell = ReadOnlyTableWidgetItem(url)
|
||||
url_cell.setData(Qt.UserRole, QVariant(bookid))
|
||||
url_cell.setToolTip('URL to add to the Reject List.')
|
||||
self.setItem(row, 0, url_cell)
|
||||
|
||||
note_cell = QTableWidgetItem(note)
|
||||
note_cell.setToolTip('Double-click to edit note.')
|
||||
self.setItem(row, 1, note_cell)
|
||||
|
||||
note_cell = EditWithComplete(self)
|
||||
|
||||
# This is a more than slightly kludgey way to get
|
||||
# EditWithComplete to *not* alpha-order the reasons, but leave
|
||||
# them in the order entered. If
|
||||
# calibre.gui2.complete2.CompleteModel.set_items ever changes,
|
||||
# this function will need to also.
|
||||
def complete_model_set_items_kludge(self, items):
|
||||
items = [unicode(x.strip()) for x in items]
|
||||
items = [x for x in items if x]
|
||||
items = tuple(items)
|
||||
self.all_items = self.current_items = items
|
||||
self.current_prefix = ''
|
||||
self.reset()
|
||||
|
||||
note_cell.lineEdit().mcompleter.model().set_items = \
|
||||
partial(complete_model_set_items_kludge,
|
||||
note_cell.lineEdit().mcompleter.model())
|
||||
|
||||
items = [note]+[ noteprefix+" - "+x for x in self.rejectreasons ]
|
||||
note_cell.update_items_cache(items)
|
||||
note_cell.show_initial_value(note)
|
||||
note_cell.set_separator(None)
|
||||
note_cell.setToolTip('Select or Edit Reject Note.')
|
||||
self.setCellWidget(row, 1, note_cell)
|
||||
|
||||
# note_cell = QTableWidgetItem(note)
|
||||
# note_cell.setToolTip('Double-click to edit note.')
|
||||
# self.setItem(row, 1, note_cell)
|
||||
|
||||
def get_reject_list(self):
|
||||
rejectrows = []
|
||||
for row in range(self.rowCount()):
|
||||
bookid = self.item(row, 0).data(Qt.UserRole).toPyObject()
|
||||
url = unicode(self.item(row, 0).text())
|
||||
note = unicode(self.item(row, 1).text())
|
||||
note = unicode(self.cellWidget(row, 1).currentText()).strip()
|
||||
rejectrows.append((bookid,url,note))
|
||||
return rejectrows
|
||||
|
||||
|
|
@ -849,6 +888,7 @@ class RejectListTableWidget(QTableWidget):
|
|||
|
||||
class RejectListDialog(SizePersistedDialog):
|
||||
def __init__(self, gui, reject_list,
|
||||
rejectreasons=[],
|
||||
header="List of Books to Reject",
|
||||
icon='rotate-right.png',
|
||||
show_delete=True,
|
||||
|
|
@ -867,7 +907,7 @@ class RejectListDialog(SizePersistedDialog):
|
|||
rejects_layout = QHBoxLayout()
|
||||
layout.addLayout(rejects_layout)
|
||||
|
||||
self.rejects_table = RejectListTableWidget(self)
|
||||
self.rejects_table = RejectListTableWidget(self,rejectreasons=rejectreasons)
|
||||
rejects_layout.addWidget(self.rejects_table)
|
||||
|
||||
button_layout = QVBoxLayout()
|
||||
|
|
@ -919,4 +959,3 @@ class RejectListDialog(SizePersistedDialog):
|
|||
|
||||
def get_deletebooks(self):
|
||||
return self.deletebooks.isChecked()
|
||||
|
||||
|
|
|
|||
|
|
@ -347,10 +347,6 @@ class FanFictionDownLoaderPlugin(InterfaceAction):
|
|||
show_copy_button=False)
|
||||
|
||||
def reject_list_urls(self):
|
||||
if self.gui.current_view().selectionModel().selectedRows() == 0 :
|
||||
self.gui.status_bar.show_message(_('No Selected Books to Get URLs From'), 3000)
|
||||
return
|
||||
|
||||
if self.is_library_view():
|
||||
book_list = map( partial(self._convert_id_to_book, good=False),
|
||||
self.gui.library_view.get_selected_ids() )
|
||||
|
|
@ -361,6 +357,10 @@ class FanFictionDownLoaderPlugin(InterfaceAction):
|
|||
#paths = view.model().paths(rows)
|
||||
book_list = map( partial(self._convert_row_to_book, good=False), rows )
|
||||
|
||||
if len(book_list) == 0 :
|
||||
self.gui.status_bar.show_message(_('No Selected Books have URLs to Reject'), 3000)
|
||||
return
|
||||
|
||||
LoopProgressDialog(self.gui,
|
||||
book_list,
|
||||
partial(self._reject_story_url_for_list, db=self.gui.current_db),
|
||||
|
|
@ -375,21 +375,27 @@ class FanFictionDownLoaderPlugin(InterfaceAction):
|
|||
self._populate_book_from_calibre_id(book,db)
|
||||
book['url'] = self._get_story_url(db,book_id=book['calibre_id'])
|
||||
elif book['path']:
|
||||
|
||||
book['url'] = self._get_story_url(db,path=book['path'])
|
||||
|
||||
if book['url'] == None:
|
||||
book['good']=False
|
||||
else:
|
||||
book['good']=True
|
||||
# get existing note, if there is one.
|
||||
book['oldrejnote']=rejecturllist.check(book['url'])
|
||||
|
||||
def _finish_reject_list_urls(self, book_list):
|
||||
# construct reject list of (calibre_id, url, note) tuples.
|
||||
reject_list = [ (x['calibre_id'],x['url'],
|
||||
"%s by %s"%(x['title'],
|
||||
', '.join(x['author']))) for x in book_list if x['good'] ]
|
||||
|
||||
# construct reject list of tuples:
|
||||
# (calibre_id, url, "title, authors", old reject note).
|
||||
reject_list = [ ( x['calibre_id'],x['url'],
|
||||
"%s by %s"%(x['title'],
|
||||
', '.join(x['author'])),
|
||||
x['oldrejnote'])
|
||||
for x in book_list if x['good'] ]
|
||||
if reject_list:
|
||||
d = RejectListDialog(self.gui,reject_list)
|
||||
d = RejectListDialog(self.gui,reject_list,
|
||||
rejectreasons=rejecturllist.get_reject_reasons())
|
||||
d.exec_()
|
||||
|
||||
if d.result() != d.Accepted:
|
||||
|
|
@ -400,6 +406,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction):
|
|||
for (bookid,url,note) in d.get_reject_list():
|
||||
bookids.append(bookid)
|
||||
rejectlist.append((url,note))
|
||||
print("Adding (%s) to Reject List: %s"%(url,note))
|
||||
|
||||
rejecturllist.add(rejectlist)
|
||||
|
||||
|
|
@ -1369,11 +1376,11 @@ make_firstimage_cover:true
|
|||
identifiers = db.get_identifiers(book_id,index_is_id=True)
|
||||
if 'url' in identifiers:
|
||||
# identifiers have :->| in url.
|
||||
print("url from ident url:"+identifiers['url'].replace('|',':'))
|
||||
# print("url from ident url:%s"%identifiers['url'].replace('|',':'))
|
||||
return identifiers['url'].replace('|',':')
|
||||
elif 'uri' in identifiers:
|
||||
# identifiers have :->| in uri.
|
||||
print("uri from ident uri:"+identifiers['uri'].replace('|',':'))
|
||||
# print("uri from ident uri:%s"%identifiers['uri'].replace('|',':'))
|
||||
return identifiers['uri'].replace('|',':')
|
||||
else:
|
||||
existingepub = None
|
||||
|
|
@ -1382,7 +1389,7 @@ make_firstimage_cover:true
|
|||
mi = get_metadata(existingepub,'EPUB')
|
||||
identifiers = mi.get_identifiers()
|
||||
if 'url' in identifiers:
|
||||
print("url from get_metadata:"+identifiers['url'].replace('|',':'))
|
||||
# print("url from get_metadata:%s"%identifiers['url'].replace('|',':'))
|
||||
return identifiers['url'].replace('|',':')
|
||||
elif path.lower().endswith('.epub'):
|
||||
existingepub = path
|
||||
|
|
@ -1392,11 +1399,11 @@ make_firstimage_cover:true
|
|||
# look for dc:source first, then scan HTML if lookforurlinhtml
|
||||
link = get_dcsource(existingepub)
|
||||
if link:
|
||||
print("url from get_dcsource:"+link)
|
||||
# print("url from get_dcsource:%s"%link)
|
||||
return link
|
||||
elif prefs['lookforurlinhtml']:
|
||||
link = get_story_url_from_html(existingepub,self._is_good_downloader_url)
|
||||
print("url from get_story_url_from_html:"+link)
|
||||
# print("url from get_story_url_from_html:%s"%link)
|
||||
return link
|
||||
return None
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue