mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Implement #111
This commit is contained in:
parent
93c915edd8
commit
ab242cc96d
53
src/libprs500/gui2/dialogs/config.py
Normal file
53
src/libprs500/gui2/dialogs/config.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
## Copyright (C) 2007 Kovid Goyal kovid@kovidgoyal.net
|
||||||
|
## This program is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published by
|
||||||
|
## the Free Software Foundation; either version 2 of the License, or
|
||||||
|
## (at your option) any later version.
|
||||||
|
##
|
||||||
|
## This program is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## 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.
|
||||||
|
from libprs500.gui2 import error_dialog
|
||||||
|
import os
|
||||||
|
|
||||||
|
from PyQt4.QtGui import QDialog
|
||||||
|
from PyQt4.QtCore import QSettings, QVariant, SIGNAL
|
||||||
|
|
||||||
|
from libprs500.gui2.dialogs.config_ui import Ui_Dialog
|
||||||
|
from libprs500.gui2 import qstring_to_unicode, choose_dir
|
||||||
|
|
||||||
|
class ConfigDialog(QDialog, Ui_Dialog):
|
||||||
|
|
||||||
|
def __init__(self, window):
|
||||||
|
QDialog.__init__(self, window)
|
||||||
|
Ui_Dialog.__init__(self)
|
||||||
|
self.setupUi(self)
|
||||||
|
|
||||||
|
settings = QSettings()
|
||||||
|
path = qstring_to_unicode(\
|
||||||
|
settings.value("database path",
|
||||||
|
QVariant(os.path.join(os.path.expanduser('~'),'library1.db'))).toString())
|
||||||
|
|
||||||
|
self.location.setText(os.path.dirname(path))
|
||||||
|
self.connect(self.browse_button, SIGNAL('clicked(bool)'), self.browse)
|
||||||
|
|
||||||
|
def browse(self):
|
||||||
|
dir = choose_dir(self, 'database location dialog', 'Select database location')
|
||||||
|
self.location.setText(dir)
|
||||||
|
|
||||||
|
def accept(self):
|
||||||
|
path = qstring_to_unicode(self.location.text())
|
||||||
|
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+'<br>Must be a directory.')
|
||||||
|
d.exec_()
|
||||||
|
elif not os.access(path, os.W_OK):
|
||||||
|
d = error_dialog(self, 'Invalid database location', 'Invalid database location.<br>Cannot write to '+path)
|
||||||
|
d.exec_()
|
||||||
|
else:
|
||||||
|
self.database_location = os.path.abspath(path)
|
||||||
|
QDialog.accept(self)
|
121
src/libprs500/gui2/dialogs/config.ui
Normal file
121
src/libprs500/gui2/dialogs/config.ui
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
<ui version="4.0" >
|
||||||
|
<class>Dialog</class>
|
||||||
|
<widget class="QDialog" name="Dialog" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle" >
|
||||||
|
<string>Configuration</string>
|
||||||
|
</property>
|
||||||
|
<property name="windowIcon" >
|
||||||
|
<iconset resource="../images.qrc" >:/images/config.svg</iconset>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" >
|
||||||
|
<item row="0" column="0" >
|
||||||
|
<widget class="QStackedWidget" name="stackedWidget" >
|
||||||
|
<widget class="QWidget" name="page" >
|
||||||
|
<layout class="QGridLayout" >
|
||||||
|
<item row="0" column="0" >
|
||||||
|
<layout class="QVBoxLayout" >
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>&Location of books database (library1.db)</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy" >
|
||||||
|
<cstring>location</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" >
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="location" />
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="browse_button" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon" >
|
||||||
|
<iconset resource="../images.qrc" >:/images/mimetypes/dir.svg</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" >
|
||||||
|
<spacer>
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" >
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="page_2" />
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" >
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox" >
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons" >
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../images.qrc" />
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>Dialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel" >
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel" >
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>Dialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel" >
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel" >
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
@ -115,9 +115,14 @@ class BooksModel(QAbstractTableModel):
|
|||||||
if isinstance(db, (QString, basestring)):
|
if isinstance(db, (QString, basestring)):
|
||||||
if isinstance(db, QString):
|
if isinstance(db, QString):
|
||||||
db = qstring_to_unicode(db)
|
db = qstring_to_unicode(db)
|
||||||
db = LibraryDatabase(os.path.expanduser(qstring_to_unicode(db)))
|
db = LibraryDatabase(os.path.expanduser(db))
|
||||||
self.db = db
|
self.db = db
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.db.close()
|
||||||
|
self.db = None
|
||||||
|
self.reset()
|
||||||
|
|
||||||
def add_books(self, paths, formats, metadata, uris=[]):
|
def add_books(self, paths, formats, metadata, uris=[]):
|
||||||
self.db.add_books(paths, formats, metadata, uris)
|
self.db.add_books(paths, formats, metadata, uris)
|
||||||
|
|
||||||
@ -392,6 +397,8 @@ class BooksView(TableView):
|
|||||||
def set_database(self, db):
|
def set_database(self, db):
|
||||||
self._model.set_database(db)
|
self._model.set_database(db)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self._model.close()
|
||||||
|
|
||||||
def migrate_database(self):
|
def migrate_database(self):
|
||||||
if self.model().database_needs_migration():
|
if self.model().database_needs_migration():
|
||||||
|
@ -12,12 +12,11 @@
|
|||||||
## You should have received a copy of the GNU General Public License along
|
## 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.,
|
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.Warning
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.Warning
|
||||||
from libprs500.ebooks.BeautifulSoup import BeautifulSoup
|
from libprs500.gui2.update import CheckForUpdates
|
||||||
from libprs500.gui2 import qstring_to_unicode
|
from libprs500 import iswindows
|
||||||
import re
|
from libprs500 import isosx
|
||||||
import urllib
|
|
||||||
import shutil
|
import os, sys, textwrap, cStringIO, collections, traceback, shutil
|
||||||
import os, sys, textwrap, cStringIO, collections, traceback
|
|
||||||
|
|
||||||
from PyQt4.QtCore import Qt, SIGNAL, QObject, QCoreApplication, \
|
from PyQt4.QtCore import Qt, SIGNAL, QObject, QCoreApplication, \
|
||||||
QSettings, QVariant, QSize, QThread, QTimer
|
QSettings, QVariant, QSize, QThread, QTimer
|
||||||
@ -34,7 +33,7 @@ from libprs500.devices.errors import FreeSpaceError
|
|||||||
from libprs500.devices.interface import Device
|
from libprs500.devices.interface import Device
|
||||||
from libprs500.gui2 import APP_UID, warning_dialog, choose_files, error_dialog, \
|
from libprs500.gui2 import APP_UID, warning_dialog, choose_files, error_dialog, \
|
||||||
initialize_file_icon_provider, BOOK_EXTENSIONS, \
|
initialize_file_icon_provider, BOOK_EXTENSIONS, \
|
||||||
pixmap_to_data, choose_dir, ORG_NAME
|
pixmap_to_data, choose_dir, ORG_NAME, qstring_to_unicode
|
||||||
from libprs500.gui2.main_window import MainWindow
|
from libprs500.gui2.main_window import MainWindow
|
||||||
from libprs500.gui2.main_ui import Ui_MainWindow
|
from libprs500.gui2.main_ui import Ui_MainWindow
|
||||||
from libprs500.gui2.device import DeviceDetector, DeviceManager
|
from libprs500.gui2.device import DeviceDetector, DeviceManager
|
||||||
@ -95,7 +94,10 @@ class Main(MainWindow, Ui_MainWindow):
|
|||||||
self.latest_version = ' '
|
self.latest_version = ' '
|
||||||
self.vanity.setText(self.vanity_template%dict(version=' ', device=' '))
|
self.vanity.setText(self.vanity_template%dict(version=' ', device=' '))
|
||||||
self.device_info = ' '
|
self.device_info = ' '
|
||||||
QTimer.singleShot(1000, self.check_for_updates)
|
self.update_checker = CheckForUpdates()
|
||||||
|
QObject.connect(self.update_checker, SIGNAL('update_found(PyQt_PyObject)'),
|
||||||
|
self.update_found)
|
||||||
|
self.update_checker.start()
|
||||||
####################### Status Bar #####################
|
####################### Status Bar #####################
|
||||||
self.status_bar = StatusBar(self.jobs_dialog)
|
self.status_bar = StatusBar(self.jobs_dialog)
|
||||||
self.setStatusBar(self.status_bar)
|
self.setStatusBar(self.status_bar)
|
||||||
@ -674,19 +676,27 @@ class Main(MainWindow, Ui_MainWindow):
|
|||||||
if d.result() == d.Accepted:
|
if d.result() == d.Accepted:
|
||||||
if os.path.dirname(self.database_path) != d.database_location:
|
if os.path.dirname(self.database_path) != d.database_location:
|
||||||
try:
|
try:
|
||||||
self.db.close()
|
|
||||||
src = open(self.database_path, 'rb')
|
|
||||||
newloc = os.path.join(d.database_location, os.path.basename(self.database_path))
|
newloc = os.path.join(d.database_location, os.path.basename(self.database_path))
|
||||||
dest = open(newloc, 'wb')
|
dest = open(newloc, 'wb')
|
||||||
self.status_bar.showMessage('Copying database to '+newloc)
|
self.status_bar.showMessage('Copying database to '+newloc)
|
||||||
shutil.copy(src, dest)
|
self.setCursor(Qt.BusyCursor)
|
||||||
|
self.library_view.setEnabled(False)
|
||||||
|
self.library_view.close()
|
||||||
|
src = open(self.database_path, 'rb')
|
||||||
|
shutil.copyfileobj(src, dest)
|
||||||
src.close()
|
src.close()
|
||||||
dest.close()
|
dest.close()
|
||||||
self.database_path = newloc
|
self.database_path = newloc
|
||||||
|
settings = QSettings()
|
||||||
|
settings.setValue("database path", QVariant(self.database_path))
|
||||||
|
os.unlink(src.name)
|
||||||
except Exception, err:
|
except Exception, err:
|
||||||
|
traceback.print_exc()
|
||||||
d = error_dialog(self, 'Could not move database', unicode(err))
|
d = error_dialog(self, 'Could not move database', unicode(err))
|
||||||
d.exec_()
|
d.exec_()
|
||||||
finally:
|
finally:
|
||||||
|
self.unsetCursor()
|
||||||
|
self.library_view.setEnabled(True)
|
||||||
self.status_bar.clearMessage()
|
self.status_bar.clearMessage()
|
||||||
self.search.clear_to_help()
|
self.search.clear_to_help()
|
||||||
self.status_bar.reset_info()
|
self.status_bar.reset_info()
|
||||||
@ -764,8 +774,8 @@ class Main(MainWindow, Ui_MainWindow):
|
|||||||
settings.beginGroup("Main Window")
|
settings.beginGroup("Main Window")
|
||||||
self.resize(settings.value("size", QVariant(QSize(800, 600))).toSize())
|
self.resize(settings.value("size", QVariant(QSize(800, 600))).toSize())
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
self.database_path = settings.value("database path",
|
self.database_path = qstring_to_unicode(settings.value("database path",
|
||||||
QVariant(os.path.join(os.path.expanduser('~'),'library1.db'))).toString()
|
QVariant(os.path.join(os.path.expanduser('~'),'library1.db'))).toString())
|
||||||
|
|
||||||
def write_settings(self):
|
def write_settings(self):
|
||||||
settings = QSettings()
|
settings = QSettings()
|
||||||
@ -795,19 +805,14 @@ class Main(MainWindow, Ui_MainWindow):
|
|||||||
self.write_settings()
|
self.write_settings()
|
||||||
e.accept()
|
e.accept()
|
||||||
|
|
||||||
def check_for_updates(self):
|
def update_found(self, version):
|
||||||
src = urllib.urlopen('http://pypi.python.org/pypi/libprs500').read()
|
os = 'windows' if iswindows else 'osx' if isosx else 'linux'
|
||||||
soup = BeautifulSoup(src)
|
url = 'https://libprs500.kovidgoyal.net/download_'+os
|
||||||
meta = soup.find('link', rel='meta', title='DOAP')
|
self.latest_version = '<span style="color:red; font-weight:bold">Latest version: <a href="%s">%s</a></span>'%(url, version)
|
||||||
if meta:
|
self.vanity.setText(self.vanity_template%(dict(version=self.latest_version,
|
||||||
src = meta['href']
|
device=self.device_info)))
|
||||||
match = re.search(r'version=(\S+)', src)
|
self.vanity.update()
|
||||||
if match:
|
|
||||||
version = match.group(1)
|
|
||||||
if version != __version__:
|
|
||||||
self.latest_version = '<span style="color:red; font-weight:bold">%s</span>'%('Latest version: '+version,)
|
|
||||||
self.vanity.setText(self.vanity_template%(dict(version=self.latest_version, device=self.device_info)))
|
|
||||||
self.vanity.update()
|
|
||||||
|
|
||||||
def main(args=sys.argv):
|
def main(args=sys.argv):
|
||||||
from PyQt4.Qt import QApplication
|
from PyQt4.Qt import QApplication
|
||||||
|
@ -697,8 +697,10 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE;
|
|||||||
def __del__(self):
|
def __del__(self):
|
||||||
global _lock_file
|
global _lock_file
|
||||||
import os
|
import os
|
||||||
if _lock_file is not None and os.path.exists(_lock_file):
|
if _lock_file is not None:
|
||||||
os.unlink(_lock_file)
|
_lock_file.close()
|
||||||
|
if os.path.exists(_lock_file.name):
|
||||||
|
os.unlink(_lock_file.name)
|
||||||
|
|
||||||
def __init__(self, dbpath):
|
def __init__(self, dbpath):
|
||||||
self.dbpath = dbpath
|
self.dbpath = dbpath
|
||||||
@ -714,6 +716,13 @@ ALTER TABLE books ADD COLUMN isbn TEXT DEFAULT "" COLLATE NOCASE;
|
|||||||
if self.user_version == 3: # Upgrade to 4
|
if self.user_version == 3: # Upgrade to 4
|
||||||
LibraryDatabase.upgrade_version3(self.conn)
|
LibraryDatabase.upgrade_version3(self.conn)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
global _lock_file
|
||||||
|
_lock_file.close()
|
||||||
|
os.unlink(_lock_file.name)
|
||||||
|
_lock_file = None
|
||||||
|
self.conn.close()
|
||||||
|
|
||||||
@apply
|
@apply
|
||||||
def user_version():
|
def user_version():
|
||||||
doc = 'The user version of this database'
|
doc = 'The user version of this database'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user