diff --git a/src/libprs500/ebooks/metadata/meta.py b/src/libprs500/ebooks/metadata/meta.py
index 8845d18e9c..acb149bd96 100644
--- a/src/libprs500/ebooks/metadata/meta.py
+++ b/src/libprs500/ebooks/metadata/meta.py
@@ -55,12 +55,21 @@ def set_metadata(stream, mi, stream_type='lrf'):
elif stream_type == 'rtf':
set_rtf_metadata(stream, mi)
-_filename_pat = re.compile(r'(?P
.+) - (?P[^_]+)')
+_filename_pat = re.compile(ur'(?P.+) - (?P[^_]+)')
-def metadata_from_filename(name):
+def get_filename_pat():
+ return _filename_pat.pattern
+
+def set_filename_pat(pat):
+ global _filename_pat
+ _filename_pat = re.compile(pat)
+
+def metadata_from_filename(name, pat=None):
name = os.path.splitext(name)[0]
mi = MetaInformation(None, None)
- match = _filename_pat.search(name)
+ if pat is None:
+ pat = _filename_pat
+ match = pat.search(name)
if match:
try:
mi.title = match.group('title')
@@ -79,6 +88,15 @@ def metadata_from_filename(name):
mi.authors = authors
except IndexError:
pass
+ try:
+ mi.series = match.group('series')
+ except IndexError:
+ pass
+ try:
+ si = match.group('series_index')
+ mi.series_index = int(si)
+ except IndexError, ValueError:
+ pass
if not mi.title:
mi.title = name
return mi
diff --git a/src/libprs500/gui2/dialogs/config.py b/src/libprs500/gui2/dialogs/config.py
index 3fce643c96..f3645a3ee8 100644
--- a/src/libprs500/gui2/dialogs/config.py
+++ b/src/libprs500/gui2/dialogs/config.py
@@ -14,12 +14,13 @@
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import os
-from PyQt4.QtGui import QDialog, QMessageBox, QListWidgetItem
+from PyQt4.QtGui import QDialog, QMessageBox, QListWidgetItem, QVBoxLayout
from PyQt4.QtCore import QSettings, QVariant, SIGNAL, QStringList, QTimer, Qt
from libprs500 import islinux
from libprs500.gui2.dialogs.config_ui import Ui_Dialog
from libprs500.gui2 import qstring_to_unicode, choose_dir, error_dialog
+from libprs500.gui2.widgets import FilenamePattern
class ConfigDialog(QDialog, Ui_Dialog):
@@ -61,6 +62,11 @@ class ConfigDialog(QDialog, Ui_Dialog):
item.setCheckState(Qt.Unchecked)
else:
item.setCheckState(Qt.Checked)
+
+ self.mbl = QVBoxLayout()
+ self.metadata_box.setLayout(self.mbl)
+ self.filename_pattern = FilenamePattern(None)
+ self.mbl.addChildWidget(self.filename_pattern)
def compact(self, toggled):
@@ -88,7 +94,10 @@ class ConfigDialog(QDialog, Ui_Dialog):
settings.setValue('network timeout', QVariant(self.timeout.value()))
path = qstring_to_unicode(self.location.text())
self.final_columns = [self.columns.item(i).checkState() == Qt.Checked for i in range(self.columns.count())]
-
+
+ pattern = self.filename_pattern.commit()
+ settings.setValue('filename pattern', QVariant(pattern))
+
if not path or not os.path.exists(path) or not os.path.isdir(path):
d = error_dialog(self, _('Invalid database location'), _('Invalid database location ')+path+_('
Must be a directory.'))
d.exec_()
diff --git a/src/libprs500/gui2/dialogs/config.ui b/src/libprs500/gui2/dialogs/config.ui
index 78f3a9c247..98ed7bc8a4 100644
--- a/src/libprs500/gui2/dialogs/config.ui
+++ b/src/libprs500/gui2/dialogs/config.ui
@@ -5,8 +5,8 @@
0
0
- 451
- 507
+ 667
+ 630
@@ -15,275 +15,360 @@
:/images/config.svg
-
- -
-
-
-
-
-
-
-
-
-
+
+
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 100
+ 16777215
+
+
+
+
+ 75
+ true
+
+
+
+
+ 32
+ 32
+
+
+
+ QListView::Static
+
+
+ QListView::TopToBottom
+
+
+ false
+
+
+
+ 80
+ 80
+
+
+
+ QListView::IconMode
+
+
+ true
+
+
+ 0
+
+
-
+
+ Basic
+
+
+ :/images/metadata.svg
+
+
+ -
+
+ Advanced
+
+
+ :/images/view.svg
+
+
+
+
+ -
+
+
+ 0
+
+
+
+
-
+
+
-
+
+
+ &Location of books database (library1.db)
+
+
+ location
+
+
+
+ -
+
+
-
+
+
+ -
+
+
+ Browse for the new database location
+
+
+ ...
+
+
+ :/images/mimetypes/dir.svg
+
+
+
+
+
+
+
+ -
+
- &Location of books database (library1.db)
+ Use &Roman numerals for series number
-
- location
+
+ true
- -
+
-
-
-
+
+
+ Default network &timeout:
+
+
+ timeout
+
+
-
-
+
- Browse for the new database location
+ Set the default timeout for network fetches (i.e. anytime libprs500 foes out to the internet to get information)
-
- ...
+
+ seconds
-
- :/images/mimetypes/dir.svg
+
+ 2
+
+
+ 120
+
+
+ 5
-
-
- -
-
-
- Use &Roman numerals for series number
-
-
- true
-
-
-
- -
-
-
-
-
-
- Default network &timeout:
-
-
- timeout
-
-
+
-
+
+
-
+
+
+ &Priority for conversion jobs:
+
+
+ priority
+
+
+
+ -
+
+
+
- -
-
-
- Set the default timeout for network fetches (i.e. anytime libprs500 foes out to the internet to get information)
+
-
+
+
+ Frequently used directories
-
- seconds
-
-
- 2
-
-
- 120
-
-
- 5
-
-
-
-
-
- -
-
-
-
-
-
- &Priority for conversion jobs:
-
-
- priority
-
-
-
- -
-
-
-
-
- -
-
-
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- Free unused diskspace from the database
-
-
- &Compact database
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
- -
-
-
- Frequently used directories
-
-
-
-
-
-
-
-
-
- true
-
-
-
- 22
- 22
-
-
-
-
- -
-
+
+
-
+
-
-
-
- Qt::Vertical
+
+
+ true
-
+
- 20
- 40
+ 22
+ 22
-
-
- -
-
-
- Add a directory to the frequently used directories list
-
-
- ...
-
-
- :/images/plus.svg
-
-
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
- Remove a directory from the frequently used directories list
-
-
- ...
-
-
- :/images/list_remove.svg
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
+
+
-
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Add a directory to the frequently used directories list
+
+
+ ...
+
+
+ :/images/plus.svg
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Remove a directory from the frequently used directories list
+
+
+ ...
+
+
+ :/images/list_remove.svg
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 392
- 16
-
-
-
-
- -
-
-
- Select visible &columns in library view
-
-
-
-
-
-
- QAbstractItemView::NoSelection
-
-
-
-
-
-
-
-
-
-
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 392
+ 16
+
+
+
+
+ -
+
+
+ Select visible &columns in library view
+
+
+
-
+
+
+ QAbstractItemView::NoSelection
+
+
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Free unused diskspace from the database
+
+
+ &Compact database
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ &Metadata from file name
+
+
+
+
+
+
+
+
- -
+
-
Qt::Horizontal
@@ -306,8 +391,8 @@
accept()
- 227
- 279
+ 231
+ 502
157
@@ -322,8 +407,8 @@
reject()
- 295
- 285
+ 299
+ 502
286
@@ -331,5 +416,21 @@
+
+ listWidget
+ currentRowChanged(int)
+ stackedWidget
+ setCurrentIndex(int)
+
+
+ 176
+ 184
+
+
+ 294
+ 9
+
+
+
diff --git a/src/libprs500/gui2/filename_pattern.ui b/src/libprs500/gui2/filename_pattern.ui
new file mode 100644
index 0000000000..6994f91629
--- /dev/null
+++ b/src/libprs500/gui2/filename_pattern.ui
@@ -0,0 +1,182 @@
+
+ Form
+
+
+
+ 0
+ 0
+ 498
+ 452
+
+
+
+ Form
+
+
+
-
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 15
+
+
+
+
+ -
+
+
+ <p>Set a regular expression pattern to use when trying to guess ebook metadata from filenames. <p>A <a href="http://docs.python.org/lib/re-syntax.html">reference</a> on the syntax of regular expressions is available.<p>Use the <b>Test</b> functionality below to test you regular expression on a few sample filenames.
+
+
+ Qt::RichText
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+ Regular &expression
+
+
+
-
+
+
+
+
+
+ -
+
+
+ &Test
+
+
+
-
+
+
-
+
+
-
+
+
+ File &name:
+
+
+ filename
+
+
+
+ -
+
+
+
+
+ -
+
+
+ Test
+
+
+
+
+
+ -
+
+
-
+
+
+ Title:
+
+
+
+ -
+
+
+ Regular expression group name (?P<title>)
+
+
+ No match
+
+
+ true
+
+
+
+ -
+
+
+ Authors:
+
+
+
+ -
+
+
+ Regular expression group name (?P<authors>)
+
+
+ No match
+
+
+ true
+
+
+
+ -
+
+
+ Series:
+
+
+
+ -
+
+
+ Regular expression group name (?P<series>)
+
+
+ No match
+
+
+ true
+
+
+
+ -
+
+
+ Series index:
+
+
+
+ -
+
+
+ Regular expression group name (?P<series_index>)
+
+
+ No match
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/libprs500/gui2/main.py b/src/libprs500/gui2/main.py
index a77ab717e7..bea7b5f7a7 100644
--- a/src/libprs500/gui2/main.py
+++ b/src/libprs500/gui2/main.py
@@ -22,7 +22,7 @@ from PyQt4.QtSvg import QSvgRenderer
from libprs500 import __version__, __appname__, islinux, sanitize_file_name
from libprs500.ptempfile import PersistentTemporaryFile
-from libprs500.ebooks.metadata.meta import get_metadata
+from libprs500.ebooks.metadata.meta import get_metadata, get_filename_pat, set_filename_pat
from libprs500.devices.errors import FreeSpaceError
from libprs500.devices.interface import Device
from libprs500.gui2 import APP_UID, warning_dialog, choose_files, error_dialog, \
@@ -806,6 +806,7 @@ class Main(MainWindow, Ui_MainWindow):
self.database_path = qstring_to_unicode(settings.value("database path",
QVariant(QString.fromUtf8(dbpath))).toString())
set_sidebar_directories(None)
+ set_filename_pat(qstring_to_unicode(settings.value('filename pattern', QVariant(get_filename_pat())).toString()))
def write_settings(self):
settings = QSettings()
diff --git a/src/libprs500/gui2/widgets.py b/src/libprs500/gui2/widgets.py
index 8652a2cf65..0557b8e15a 100644
--- a/src/libprs500/gui2/widgets.py
+++ b/src/libprs500/gui2/widgets.py
@@ -12,19 +12,71 @@
## You should have received a copy of the GNU General Public License along
## with this program; if not, write to the Free Software Foundation, Inc.,
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
'''
-Miscellanous widgets used in the GUI
+Miscellaneous widgets used in the GUI
'''
+import re
from PyQt4.QtGui import QListView, QIcon, QFont, QLabel, QListWidget, \
QListWidgetItem, QTextCharFormat, QApplication, \
- QSyntaxHighlighter, QCursor, QColor
+ QSyntaxHighlighter, QCursor, QColor, QWidget
from PyQt4.QtCore import QAbstractListModel, QVariant, Qt, QSize, SIGNAL, \
QObject, QRegExp, QSettings
from libprs500.gui2.jobs import DetailView
-from libprs500.gui2 import human_readable, NONE, TableView
+from libprs500.gui2 import human_readable, NONE, TableView, qstring_to_unicode, error_dialog
+from libprs500.gui2.filename_pattern_ui import Ui_Form
from libprs500 import fit_image, get_font_families
+from libprs500.ebooks.metadata.meta import get_filename_pat, metadata_from_filename, \
+ set_filename_pat
+
+class FilenamePattern(QWidget, Ui_Form):
+
+ def __init__(self, parent):
+ QWidget.__init__(self, parent)
+ self.setupUi(self)
+
+ self.connect(self.test_button, SIGNAL('clicked()'), self.do_test)
+ self.connect(self.re, SIGNAL('returnPressed()'), self.do_test)
+ self.re.setText(get_filename_pat())
+
+ def do_test(self):
+ try:
+ pat = self.pattern()
+ except Exception, err:
+ error_dialog(self, _('Invalid regular expression'),
+ _('Invalid regular expression: %s')%err).exec_()
+ return
+ mi = metadata_from_filename(qstring_to_unicode(self.filename.text()), pat)
+ if mi.title:
+ self.title.setText(mi.title)
+ else:
+ self.title.setText(_('No match'))
+ if mi.authors:
+ self.authors.setText(', '.join(mi.authors))
+ else:
+ self.authors.setText(_('No match'))
+
+ if mi.series:
+ self.series.setText(mi.series)
+ else:
+ self.series.setText(_('No match'))
+
+ if mi.series_index is not None:
+ self.series_index.setText(str(mi.series_index))
+ else:
+ self.series_index.setText(_('No match'))
+
+ def pattern(self):
+ pat = qstring_to_unicode(self.re.text())
+ return re.compile(pat)
+
+ def commit(self):
+ pat = self.pattern()
+ set_filename_pat(pat)
+ return pat.pattern
+
+
+
class ImageView(QLabel):