diff --git a/calibre-plugin/config.py b/calibre-plugin/config.py index ab6dfc5..073bc02 100644 --- a/calibre-plugin/config.py +++ b/calibre-plugin/config.py @@ -18,10 +18,10 @@ from PyQt4.Qt import (QDialog, QWidget, QVBoxLayout, QHBoxLayout, QLabel, from calibre.utils.config import JSONConfig from calibre.gui2.ui import get_gui -from calibre_plugins.fanfictiondownloader_plugin.prefs import prefs +from calibre_plugins.fanfictiondownloader_plugin.prefs import prefs, PREFS_NAMESPACE from calibre_plugins.fanfictiondownloader_plugin.dialogs \ import (UPDATE, UPDATEALWAYS, OVERWRITE, collision_order, RejectListDialog, - EditTextDialog) + EditTextDialog, RejectUrlEntry) from calibre_plugins.fanfictiondownloader_plugin.fanficdownloader.adapters \ import (getConfigSections, getNormalStoryURL) @@ -37,22 +37,16 @@ class RejectURLList: self.sync_lock = threading.RLock() self.listcache = None - def _read_list_from_text(self,text,addreasontext=None): - cache = {} + def _read_list_from_text(self,text,addreasontext=''): + cache = OrderedDict() + + #print("_read_list_from_text") for line in text.splitlines(): - if ',' in line: - (rejurl,note) = line.split(',',1) - else: - (rejurl,note) = (line,'') - rejurl = getNormalStoryURL(rejurl) - if rejurl: - if addreasontext and note: - note = note +" - "+addreasontext - elif addreasontext: - note = addreasontext - cache[rejurl] = note - return cache - + rue = RejectUrlEntry(line,addreasontext=addreasontext,fromline=True) + #print("rue.url:%s"%rue.url) + if rue.valid: + cache[rue.url] = rue + return cache def _get_listcache(self): if self.listcache == None: @@ -60,26 +54,35 @@ class RejectURLList: return self.listcache def _save_list(self,listcache): - rejectlist = [] - for url in listcache: - rejectlist.append("%s,%s"%(url,listcache[url])) - - self.prefs['rejecturls'] = '\n'.join(rejectlist) + #print("_save_list") + self.prefs['rejecturls'] = '\n'.join([x.to_line() for x in listcache.values()]) self.prefs.save_to_db() self.listcache = None def clear_cache(self): self.listcache = None + # true if url is in list. def check(self,url): + with self.sync_lock: + listcache = self._get_listcache() + return url in listcache + + def get_note(self,url): with self.sync_lock: listcache = self._get_listcache() if url in listcache: - note = listcache[url] - return note - + return listcache[url].note # not found - return None + return '' + + def get_full_note(self,url): + with self.sync_lock: + listcache = self._get_listcache() + if url in listcache: + return listcache[url].fullnote() + # not found + return '' def remove(self,url): with self.sync_lock: @@ -89,27 +92,26 @@ class RejectURLList: self._save_list(listcache) def add_text(self,rejecttext,addreasontext): - self.add(self._read_list_from_text(rejecttext,addreasontext).items()) + self.add(self._read_list_from_text(rejecttext,addreasontext).values()) def add(self,rejectlist,clear=False): - # rejectlist=list of (url,note) tuples. with self.sync_lock: if clear: - listcache={} + listcache=OrderedDict() else: listcache = self._get_listcache() - for (url,note) in rejectlist: - listcache[url]=note + for l in rejectlist: + listcache[l.url]=l self._save_list(listcache) def get_list(self): - return copy.deepcopy(self._get_listcache()) + return self._get_listcache().values() def get_reject_reasons(self): return self.prefs['rejectreasons'].splitlines() rejecturllist = RejectURLList(prefs) - + class ConfigWidget(QWidget): def __init__(self, plugin_action): @@ -418,12 +420,8 @@ class BasicTab(QWidget): ShowDefaultsIniDialog(self.windowIcon(),text,self).exec_() def show_rejectlist(self): - rejectlist = [] - for (url,note) in rejecturllist.get_list().items(): - rejectlist.append((None,url,note,note)) - d = RejectListDialog(self, - rejectlist, + rejecturllist.get_list(), rejectreasons=rejecturllist.get_reject_reasons(), header="Edit Reject URLs List", show_delete=False, @@ -433,11 +431,7 @@ class BasicTab(QWidget): if d.result() != d.Accepted: return - rejectlist=[] - for (bookid,url,note) in d.get_reject_list(): - rejectlist.append((url,note)) - - rejecturllist.add(rejectlist,clear=True) + rejecturllist.add(d.get_reject_list(),clear=True) def show_reject_reasons(self): d = EditTextDialog(self, @@ -452,11 +446,11 @@ class BasicTab(QWidget): def add_reject_urls(self): d = EditTextDialog(self, - "http://example.com?story.php?sid=5,Reason why I rejected it", + "http://example.com/story.php?sid=5,Reason why I rejected it\nhttp://example.com/story.php?sid=6,Title by Author - Reason why I rejected it", icon=self.windowIcon(), title="Add Reject URLs", - label="Add Reject URLs. Use: http://...,note
Invalid story URLs will be ignored.", - tooltip="One URL per line, everything after , will be put in the note.", + label="Add Reject URLs. Use: http://...,note or http://...,title by author - note
Invalid story URLs will be ignored.", + tooltip="One URL per line:\nhttp://...,note\nhttp://...,title by author - note", rejectreasons=rejecturllist.get_reject_reasons(), reasonslabel='Add this reason to all URLs added:') d.exec_() diff --git a/calibre-plugin/dialogs.py b/calibre-plugin/dialogs.py index 8d3db7f..cb680d2 100644 --- a/calibre-plugin/dialogs.py +++ b/calibre-plugin/dialogs.py @@ -7,7 +7,7 @@ __license__ = 'GPL v3' __copyright__ = '2011, Jim Miller' __docformat__ = 'restructuredtext en' -import traceback +import traceback, re from functools import partial import urllib @@ -27,6 +27,7 @@ from calibre_plugins.fanfictiondownloader_plugin.common_utils \ ImageTitleLayout, get_icon) from calibre_plugins.fanfictiondownloader_plugin.fanficdownloader.geturls import get_urls_from_html, get_urls_from_text +from calibre_plugins.fanfictiondownloader_plugin.fanficdownloader.adapters import getNormalStoryURL SKIP=u'Skip' ADDNEW=u'Add New Book' @@ -46,7 +47,62 @@ collision_order=[SKIP, anthology_collision_order=[UPDATE, UPDATEALWAYS, OVERWRITEALWAYS] + +class RejectUrlEntry: + + matchpat=re.compile(r"^(?P[^,]+)(,(?P(((?P.+) by (?P<auth>.+?)( - (?P<note>.+))?)|.*)))?$") + + def __init__(self,url_or_line,note=None,title=None,auth=None, + addreasontext=None,fromline=False): + self.url=url_or_line + self.note=note + self.title=title + self.auth=auth + self.valid=False + + if fromline: + mc = re.match(self.matchpat,url_or_line) + if mc: + #print("mc:%s"%mc.groupdict()) + (url,title,auth,note) = mc.group('url','title','auth','note') + if not mc.group('title'): + title='' + auth='' + note=mc.group('fullnote') + self.url=url + self.note=note + self.title=title + self.auth=auth + + if not self.note: + if addreasontext: + self.note = addreasontext + else: + self.note = '' + else: + if addreasontext: + self.note = self.note + ' - ' + addreasontext + + self.url = getNormalStoryURL(self.url) + self.valid = self.url != None + + def to_line(self): + # always 'url,' + return self.url+","+self.fullnote() + + def fullnote(self): + retval = "" + if self.title and self.auth: + retval = retval + "%s by %s"%(self.title,self.auth) + if self.note: + retval = retval + " - " + + if self.note: + retval = retval + self.note + + return retval + # 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 @@ -74,18 +130,8 @@ class DroppableQTextEdit(QTextEdit): def dropEvent(self,event): # print("event:%s"%event) - # print("event.mimeData():%s"%event.mimeData()) - # print("event.mimeData().text():%s"%str(event.mimeData().text())) - # print("event.mimeData().data():%s"%str(event.mimeData().data())) - # print("event.mimeData().formats():%s"%[str(f) for f in event.mimeData().formats()]) - # for f in event.mimeData().formats(): - # try: - # print("event.mimeData().data('%s'):%s"%(f,event.mimeData().data(f))) - # except: - # print("failed %s"%f) mimetype='text/uri-list' - # print("event.mimeData().data('%s'):%s"%(mimetype,event.mimeData().data(mimetype))) urllist=[] filelist="%s"%event.mimeData().data(mimetype) @@ -272,13 +318,6 @@ class AddNewDialog(SizePersistedDialog): if not self.merge: self.fileform.setCurrentIndex(self.fileform.findText(self.prefs['fileform'])) - # if url_list_text: - # self.fileform.setVisible(True) - # self.formlabel.setVisible(True) - # else: - # self.fileform.setVisible(False) - # self.formlabel.setVisible(False) - if self.merge and not self.newmerge: self.set_collisions() i = self.collision.findText(self.prefs['collision']) @@ -571,11 +610,7 @@ class UpdateExistingDialog(SizePersistedDialog): button_layout = QVBoxLayout() books_layout.addLayout(button_layout) - # self.move_up_button = QtGui.QToolButton(self) - # self.move_up_button.setToolTip('Move selected books up the list') - # self.move_up_button.setIcon(QIcon(I('arrow-up.png'))) - # self.move_up_button.clicked.connect(self.books_table.move_rows_up) - # button_layout.addWidget(self.move_up_button) + spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) button_layout.addItem(spacerItem) self.remove_button = QtGui.QToolButton(self) @@ -585,11 +620,6 @@ class UpdateExistingDialog(SizePersistedDialog): button_layout.addWidget(self.remove_button) spacerItem1 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) button_layout.addItem(spacerItem1) - # self.move_down_button = QtGui.QToolButton(self) - # self.move_down_button.setToolTip('Move selected books down the list') - # self.move_down_button.setIcon(QIcon(I('arrow-down.png'))) - # self.move_down_button.clicked.connect(self.books_table.move_rows_down) - # button_layout.addWidget(self.move_down_button) options_layout = QHBoxLayout() @@ -615,7 +645,6 @@ class UpdateExistingDialog(SizePersistedDialog): i = self.collision.findText(prefs['collision']) if i > -1: self.collision.setCurrentIndex(i) - # self.collision.setToolTip('Overwrite will replace the existing story. Add New will create a new story with the same title and author.') label.setBuddy(self.collision) options_layout.addWidget(self.collision) @@ -724,11 +753,9 @@ class StoryListTableWidget(QTableWidget): self.setItem(row, 2, AuthorTableWidgetItem(", ".join(book['author']), ", ".join(book['author_sort']))) url_cell = ReadOnlyTableWidgetItem(book['url']) - #url_cell.setData(Qt.UserRole, QVariant(book['url'])) self.setItem(row, 3, url_cell) comment_cell = ReadOnlyTableWidgetItem(book['comment']) - #comment_cell.setData(Qt.UserRole, QVariant(book)) self.setItem(row, 4, comment_cell) def get_books(self): @@ -762,56 +789,6 @@ class StoryListTableWidget(QTableWidget): self.selectRow(row) self.scrollToItem(self.currentItem()) - def move_rows_up(self): - self.setFocus() - rows = self.selectionModel().selectedRows() - if len(rows) == 0: - return - first_sel_row = rows[0].row() - if first_sel_row <= 0: - return - # Workaround for strange selection bug in Qt which "alters" the selection - # in certain circumstances which meant move down only worked properly "once" - selrows = [] - for row in rows: - selrows.append(row.row()) - selrows.sort() - for selrow in selrows: - self.swap_row_widgets(selrow - 1, selrow + 1) - scroll_to_row = first_sel_row - 1 - if scroll_to_row > 0: - scroll_to_row = scroll_to_row - 1 - self.scrollToItem(self.item(scroll_to_row, 0)) - - def move_rows_down(self): - self.setFocus() - rows = self.selectionModel().selectedRows() - if len(rows) == 0: - return - last_sel_row = rows[-1].row() - if last_sel_row == self.rowCount() - 1: - return - # Workaround for strange selection bug in Qt which "alters" the selection - # in certain circumstances which meant move down only worked properly "once" - selrows = [] - for row in rows: - selrows.append(row.row()) - selrows.sort() - for selrow in reversed(selrows): - self.swap_row_widgets(selrow + 2, selrow) - scroll_to_row = last_sel_row + 1 - if scroll_to_row < self.rowCount() - 1: - scroll_to_row = scroll_to_row + 1 - self.scrollToItem(self.item(scroll_to_row, 0)) - - def swap_row_widgets(self, src_row, dest_row): - self.blockSignals(True) - self.insertRow(dest_row) - for col in range(0, self.columnCount()): - self.setItem(dest_row, col, self.takeItem(src_row, col)) - self.removeRow(src_row) - self.blockSignals(False) - class RejectListTableWidget(QTableWidget): def __init__(self, parent,rejectreasons=[]): @@ -819,81 +796,53 @@ class RejectListTableWidget(QTableWidget): self.setSelectionBehavior(QAbstractItemView.SelectRows) self.rejectreasons = rejectreasons - def on_headersection_clicked(self): - self.setSortingEnabled(True) - def populate_table(self, reject_list): self.clear() self.setAlternatingRowColors(True) self.setRowCount(len(reject_list)) - header_labels = ['URL', 'Note'] + header_labels = ['URL', 'Title', 'Author', 'Note'] self.setColumnCount(len(header_labels)) self.setHorizontalHeaderLabels(header_labels) self.horizontalHeader().setStretchLastSection(True) #self.verticalHeader().setDefaultSectionSize(24) self.verticalHeader().hide() - # need sortingEnbled to sort, but off to up & down. - self.connect(self.horizontalHeader(), - SIGNAL('sectionClicked(int)'), - self.on_headersection_clicked) - + # it's generally recommended to enable sort after pop, not + # before. But then it needs to be sorted on a column and I'd + # rather keep the order given. + self.setSortingEnabled(True) # row is just row number. for row, rejectrow in enumerate(reject_list): + #print("populating table:%s"%rejectrow.to_line()) self.populate_table_row(row,rejectrow) self.resizeColumnsToContents() - self.setMinimumColumnWidth(1, 100) - self.setMinimumColumnWidth(2, 100) + self.setMinimumColumnWidth(0, 100) + self.setMinimumColumnWidth(3, 100) self.setMinimumSize(300, 0) def setMinimumColumnWidth(self, col, minimum): if self.columnWidth(col) < minimum: self.setColumnWidth(col, minimum) - def populate_table_row(self, row, 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 - - if len(noteprefix) > 0: - noteprefix = noteprefix+' - ' - - 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) + def populate_table_row(self, row, rej): + self.setItem(row, 0, ReadOnlyTableWidgetItem(rej.url)) + self.setItem(row, 1, ReadOnlyTableWidgetItem(rej.title)) + self.setItem(row, 2, ReadOnlyTableWidgetItem(rej.auth)) + note_cell = EditWithComplete(self) - 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 ] + items = [rej.note]+self.rejectreasons note_cell.update_items_cache(items) - note_cell.show_initial_value(note) + note_cell.show_initial_value(rej.note) note_cell.set_separator(None) note_cell.setToolTip('Select or Edit Reject Note.') - self.setCellWidget(row, 1, note_cell) + self.setCellWidget(row, 3, 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.cellWidget(row, 1).currentText()).strip() - rejectrows.append((bookid,url,note)) - return rejectrows - def remove_selected_rows(self): self.setFocus() rows = self.selectionModel().selectedRows() @@ -916,57 +865,6 @@ class RejectListTableWidget(QTableWidget): self.selectRow(row) self.scrollToItem(self.currentItem()) - def move_rows_up(self): - self.setFocus() - rows = self.selectionModel().selectedRows() - if len(rows) == 0: - return - first_sel_row = rows[0].row() - if first_sel_row <= 0: - return - # Workaround for strange selection bug in Qt which "alters" the selection - # in certain circumstances which meant move down only worked properly "once" - selrows = [] - for row in rows: - selrows.append(row.row()) - selrows.sort() - for selrow in selrows: - self.swap_row_widgets(selrow - 1, selrow + 1) - scroll_to_row = first_sel_row - 1 - if scroll_to_row > 0: - scroll_to_row = scroll_to_row - 1 - self.scrollToItem(self.item(scroll_to_row, 0)) - - def move_rows_down(self): - self.setFocus() - rows = self.selectionModel().selectedRows() - if len(rows) == 0: - return - last_sel_row = rows[-1].row() - if last_sel_row == self.rowCount() - 1: - return - # Workaround for strange selection bug in Qt which "alters" the selection - # in certain circumstances which meant move down only worked properly "once" - selrows = [] - for row in rows: - selrows.append(row.row()) - selrows.sort() - for selrow in reversed(selrows): - self.swap_row_widgets(selrow + 2, selrow) - scroll_to_row = last_sel_row + 1 - if scroll_to_row < self.rowCount() - 1: - scroll_to_row = scroll_to_row + 1 - self.scrollToItem(self.item(scroll_to_row, 0)) - - def swap_row_widgets(self, src_row, dest_row): - self.blockSignals(True) - self.setSortingEnabled(False) - self.insertRow(dest_row) - for col in range(0, self.columnCount()): - self.setItem(dest_row, col, self.takeItem(src_row, col)) - self.removeRow(src_row) - self.blockSignals(False) - class RejectListDialog(SizePersistedDialog): def __init__(self, gui, reject_list, rejectreasons=[], @@ -995,21 +893,13 @@ class RejectListDialog(SizePersistedDialog): rejects_layout.addLayout(button_layout) spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) button_layout.addItem(spacerItem) - # self.move_up_button = QtGui.QToolButton(self) - # self.move_up_button.setToolTip('Move selected books up the list') - # self.move_up_button.setIcon(QIcon(I('arrow-up.png'))) - # self.move_up_button.clicked.connect(self.books_table.move_rows_up) - # button_layout.addWidget(self.move_up_button) + self.remove_button = QtGui.QToolButton(self) self.remove_button.setToolTip('Remove selected URL(s) from the list') self.remove_button.setIcon(get_icon('list_remove.png')) self.remove_button.clicked.connect(self.remove_from_list) button_layout.addWidget(self.remove_button) - # self.move_down_button = QtGui.QToolButton(self) - # self.move_down_button.setToolTip('Move selected books down the list') - # self.move_down_button.setIcon(QIcon(I('arrow-down.png'))) - # self.move_down_button.clicked.connect(self.books_table.move_rows_down) - # button_layout.addWidget(self.move_down_button) + spacerItem1 = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) button_layout.addItem(spacerItem1) @@ -1056,10 +946,21 @@ class RejectListDialog(SizePersistedDialog): self.rejects_table.remove_selected_rows() def get_reject_list(self): - return self.rejects_table.get_reject_list() + rejectrows = [] + for row in range(self.rejects_table.rowCount()): + url = unicode(self.rejects_table.item(row, 0).text()).strip() + title = unicode(self.rejects_table.item(row, 1).text()).strip() + auth = unicode(self.rejects_table.item(row, 2).text()).strip() + note = unicode(self.rejects_table.cellWidget(row, 3).currentText()).strip() + rejectrows.append(RejectUrlEntry(url,note,title,auth,self.get_reason_text())) + return rejectrows def get_reason_text(self): - return unicode(self.reason_edit.currentText()).strip() + try: + return unicode(self.reason_edit.currentText()).strip() + except: + # doesn't have self.reason_edit when editing existing list. + return None def get_deletebooks(self): return self.deletebooks.isChecked() diff --git a/calibre-plugin/ffdl_plugin.py b/calibre-plugin/ffdl_plugin.py index dd2fc96..abd04e0 100644 --- a/calibre-plugin/ffdl_plugin.py +++ b/calibre-plugin/ffdl_plugin.py @@ -47,7 +47,7 @@ from calibre_plugins.fanfictiondownloader_plugin.dialogs import ( AddNewDialog, UpdateExistingDialog, LoopProgressDialog, UserPassDialog, AboutDialog, CollectURLDialog, RejectListDialog, OVERWRITE, OVERWRITEALWAYS, UPDATE, UPDATEALWAYS, ADDNEW, SKIP, CALIBREONLY, - NotGoingToDownload ) + NotGoingToDownload, RejectUrlEntry ) # because calibre immediately transforms html into zip and don't want # to have an 'if html'. db.has_format is cool with the case mismatch, @@ -403,17 +403,17 @@ class FanFictionDownLoaderPlugin(InterfaceAction): # want title/author, too, for rejects. self.populate_book_from_calibre_id(book,db) if book['url']: - # get existing note, if there is one. - book['oldrejnote']=rejecturllist.check(book['url']) + # get existing note, if on rejected list. + book['oldrejnote']=rejecturllist.get_note(book['url']) def reject_list_urls_finish(self, book_list): # 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']) + reject_list = [ RejectUrlEntry(x['url'], + x['oldrejnote'], + x['title'], + ', '.join(x['author'])) for x in book_list if x['good'] ] if reject_list: d = RejectListDialog(self.gui,reject_list, @@ -423,19 +423,7 @@ class FanFictionDownLoaderPlugin(InterfaceAction): if d.result() != d.Accepted: return - bookids=[] - rejectlist=[] - addreasontext=d.get_reason_text() - for (bookid,url,note) in d.get_reject_list(): - bookids.append(bookid) - if addreasontext and note: - note = note +" - "+addreasontext - elif addreasontext: - note = addreasontext - rejectlist.append((url,note)) - print("Adding (%s) to Reject List: %s"%(url,note)) - - rejecturllist.add(rejectlist) + rejecturllist.add(d.get_reject_list()) if d.get_deletebooks(): self.gui.iactions['Remove Books'].delete_books() @@ -675,12 +663,13 @@ class FanFictionDownLoaderPlugin(InterfaceAction): print("url:%s"%url) if not merge: # skip reject list when merging. - rejnote = rejecturllist.check(url) - if rejnote: + if rejecturllist.check(url): + rejnote = rejecturllist.get_full_note(url) if question_dialog(self.gui, 'Reject URL?', - '<p>Reject URL?</p>'+ - '<p>%s is on the Reject URL list:<br />"%s"</p>'%(url,rejnote)+ - "<p>Click 'No' to download anyway.</p>", + '<h3>Reject URL?</h3>'+ + '<p><b>%s</b> is on your Reject URL list:</p><p>"<b>%s</b>"</p>'%(url,rejnote)+ + "<p>Click '<b>Yes</b>' to Reject.</p>"+ + "<p>Click '<b>No</b>' to download anyway.</p>", show_copy_button=False): book['comment'] = "Story on Reject URLs list (%s)."%rejnote book['good']=False @@ -689,9 +678,10 @@ class FanFictionDownLoaderPlugin(InterfaceAction): return else: if question_dialog(self.gui, 'Remove Reject URL?', - "<p>Remove URL from Reject List?</p>"+ - '<p>%s is on the Reject URL list:<br />"%s"</p>'%(url,rejnote)+ - "<p>Click 'Yes' to remove it from the list and download,<br /> 'No' to download, but leave it on the Reject list.</p>", + "<h3>Remove URL from Reject List?</h3>"+ + '<p><b>%s</b> is on your Reject URL list:</p><p>"<b>%s</b>"</p>'%(url,rejnote)+ + "<p>Click '<b>Yes</b>' to remove it from the list,</p>"+ + "<p>Click '<b>No</b>' to leave it on the list.</p>", show_copy_button=False): rejecturllist.remove(url) @@ -749,10 +739,11 @@ class FanFictionDownLoaderPlugin(InterfaceAction): # print("searchstr:%s"%searchstr) # print("identicalbooks:%s"%identicalbooks) if len(identicalbooks) > 0 and question_dialog(self.gui, 'Skip Story?', - '<p>Skip Anthology Story?</p>'+ - '<p>Story "%s" is in series "<a href="%s">%s</a>" that you have an anthology book for.</p>'% + '<h3>Skip Anthology Story?</h3>'+ + '<p>"<b>%s</b>" is in series "<b><a href="%s">%s</a></b>" that you have an anthology book for.</p>'% (story.getMetadata('title'),story.getMetadata('seriesUrl'),series[:series.index(' [')])+ - "<p>Click 'No' to download anyway.</p>", + "<p>Click '<b>Yes</b>' to Skip.</p>"+ + "<p>Click '<b>No</b>' to download anyway.</p>", show_copy_button=False): book['comment'] = "Story in Series Anthology(%s)."%series book['title'] = story.getMetadata('title') diff --git a/fanficdownloader/adapters/__init__.py b/fanficdownloader/adapters/__init__.py index 12e0687..53d9007 100644 --- a/fanficdownloader/adapters/__init__.py +++ b/fanficdownloader/adapters/__init__.py @@ -153,7 +153,7 @@ def getAdapter(config,url): #logger.debug("trying url:"+url) (cls,fixedurl) = getClassFor(url) - logger.debug("fixedurl:"+fixedurl) + #logger.debug("fixedurl:"+fixedurl) if cls: adapter = cls(config,fixedurl) # raises InvalidStoryURL return adapter