diff --git a/Makefile b/Makefile index 9fdc37c298..85d2df0038 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,11 @@ APIDOCS=/var/www/libprs500.kovidgoyal.net/htdocs/apidocs +targets: + @echo Targets are: installer doc -all: doc sdist egg - -sdist: - python setup.py sdist --formats=gztar,zip - -egg: - python setup.py bdist_egg +installer: + @scp dist/libprs500-*.exe castalia:/var/www/vhosts/kovidgoyal.net/subdomains/libprs500/httpdocs/downloads/ + @ssh castalia chmod a+r /var/www/vhosts/kovidgoyal.net/subdomains/libprs500/httpdocs/downloads/\* + @echo Update link on the libprs500 wiki doc: epydoc --config epydoc.conf diff --git a/installer.nsi b/installer.nsi index d086c820a4..34d076f0dc 100644 --- a/installer.nsi +++ b/installer.nsi @@ -1,24 +1,179 @@ +SetCompressor lzma +ShowInstDetails show +ShowUnInstDetails show + ;------------------------------------------------------------------------------------------------------ ;Include Modern UI + !include "AddToPath.nsh" + !include "XPUI.nsh" + !define XPUI_SKIN "Windows XP" + +;------------------------------------------------------------------------------------------------------ +;Variables +Var STARTMENU_FOLDER +Var MUI_TEMP - !include "MUI.nsh" +!define PRODUCT_NAME "libprs500" +!define XPUI_BRANDINGTEXT "${PRODUCT_NAME} created by Kovid Goyal" +!define PRODUCT_VERSION "0.3.12" +!define WEBSITE "https://libprs500.kovidgoyal.net" +!define PY2EXE_DIR "C:\libprs500" +!define LIBUSB_DIR "C:\libusb-prs500" +!define QT_DIR "C:\Qt\4.2.3\bin" ;------------------------------------------------------------------------------------------------------ ;General ;Name and file - Name "libprs500" - OutFile "Basic.exe" + Name "${PRODUCT_NAME}" + OutFile "dist\${PRODUCT_NAME}-${PRODUCT_VERSION}.exe" ;Default installation folder - InstallDir "$PROGRAMFILES\libprs500" + InstallDir "$PROGRAMFILES\${PRODUCT_NAME}" ;Get installation folder from registry if available - InstallDirRegKey HKCU "Software\libprs500" "" + InstallDirRegKey HKCU "Software\${PRODUCT_NAME}" "" + + ;Vista redirects $SMPROGRAMS to all users without this + RequestExecutionLevel admin ;------------------------------------------------------------------------------------------------------ ;Interface Settings + !define MUI_HEADERIMAGE + !define MUI_HEADERIMAGE_BITMAP "icons\library.ico" !define MUI_ABORTWARNING -;------------------------------------------------------------------------------------------------------ \ No newline at end of file +;------------------------------------------------------------------------------------------------------ +;Pages + + !insertmacro MUI_PAGE_WELCOME + !insertmacro MUI_PAGE_LICENSE "LICENSE" + !insertmacro MUI_PAGE_COMPONENTS + !insertmacro MUI_PAGE_DIRECTORY + ;Start Menu Folder Page Configuration + !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU" + !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\${PRODUCT_NAME}" + !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" + + !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER + !insertmacro MUI_PAGE_INSTFILES + + !insertmacro MUI_UNPAGE_CONFIRM + !insertmacro MUI_UNPAGE_INSTFILES + !insertmacro MUI_UNPAGE_FINISH +;------------------------------------------------------------------------------------------------------ +;Languages + + !insertmacro MUI_LANGUAGE "English" +;------------------------------------------------------------------------------------------------------ +;Installer Sections + +Function .onInit + ; Prevent multiple instances of the installer from running + System::Call 'kernel32::CreateMutexA(i 0, i 0, t "${PRODUCT_NAME}-setup") i .r1 ?e' + Pop $R0 + + StrCmp $R0 0 +3 + MessageBox MB_OK|MB_ICONEXCLAMATION "The installer is already running." + Abort + +FunctionEnd + + +Section "libprs500" Seclibprs500 + + SetOutPath "$INSTDIR" + + ;ADD YOUR OWN FILES HERE... + File /r "${PY2EXE_DIR}\*" + ; The next line can be commented out once py2exe starts including QtSvg.dll + File "${QT_DIR}\QtSvg4.dll" + + SetOutPath "$INSTDIR\driver" + File "${LIBUSB_DIR}\*.dll" + File "${LIBUSB_DIR}\*.sys" + File "${LIBUSB_DIR}\*.cat" + File "${LIBUSB_DIR}\*.inf" + + SetOutPath "$SYSDIR" + File "${LIBUSB_DIR}\libusb0.dll" + DetailPrint " " + + DetailPrint "Installing USB driver (this may take a few seconds) ..." + ExecWait '"rundll32" libusb0.dll,usb_install_driver_np_rundll "$INSTDIR\driver\prs500.inf"' $0 + DetailPrint "rundll32 returned exit code $0" + IfErrors 0 +2 + MessageBox MB_OK 'You may need to run the following at the console in order for the SONY Reader to be detected:\r\n"rundll32" libusb0.dll,usb_install_driver_np_rundll "$INSTDIR\driver\prs500.inf"' + DetailPrint " " + + + ;Store installation folder + WriteRegStr HKCU "Software\${PRODUCT_NAME}" "" $INSTDIR + + ;Create uninstaller + WriteUninstaller "$INSTDIR\Uninstall.exe" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \ + "DisplayName" "${PRODUCT_NAME} -- E-book management software" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \ + "UninstallString" "$INSTDIR\Uninstall.exe" + + SetOutPath "$INSTDIR" + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + + ;Create shortcuts + WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${WEBSITE}" + CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER" + CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\libprs500.lnk" "$INSTDIR\prs500-gui.exe" + CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url" + CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe" + CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\prs500-gui.exe" + + !insertmacro MUI_STARTMENU_WRITE_END + + ;Add the installation directory to PATH for the commandline tools + Push "$INSTDIR" + Call AddToPath + +SectionEnd +;------------------------------------------------------------------------------------------------------ +;Descriptions + + ;Language strings + LangString DESC_Seclibprs500 ${LANG_ENGLISH} "The GUI and command-line tools for working with ebooks" + + ;Assign language strings to sections + !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${Seclibprs500} $(DESC_Seclibprs500) + !insertmacro MUI_FUNCTION_DESCRIPTION_END +;------------------------------------------------------------------------------------------------------ +;Uninstaller Section + +Section "Uninstall" + ;ADD YOUR OWN FILES HERE... + RMDir /r "$INSTDIR" + !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP + RMDir /r "$SMPROGRAMS\$MUI_TEMP" + ;Delete empty start menu parent diretories + StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP" + + startMenuDeleteLoop: + ClearErrors + RMDir $MUI_TEMP + GetFullPathName $MUI_TEMP "$MUI_TEMP\.." + + IfErrors startMenuDeleteLoopDone + + StrCmp $MUI_TEMP $SMPROGRAMS startMenuDeleteLoopDone startMenuDeleteLoop + startMenuDeleteLoopDone: + Delete "$DESKTOP\${PRODUCT_NAME}.lnk" + + DeleteRegKey /ifempty HKCU "Software\${PRODUCT_NAME}" + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" + ; Remove installation directory from PATH + Push "$INSTDIR" + Call un.RemoveFromPath + +SectionEnd + + diff --git a/setup.py b/setup.py index 24eba2a114..38be1c81f6 100644 --- a/setup.py +++ b/setup.py @@ -13,21 +13,42 @@ ## with this program; if not, write to the Free Software Foundation, Inc., ## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #!/usr/bin/env python -import sys +import sys, re +sys.path.append('src') +from libprs500 import __version__ as VERSION import ez_setup ez_setup.use_setuptools() -try: - import py2exe - console = [{'script' : 'src/libprs500/cli/main.py', 'dest_base':'prs500'}] - windows = [{'script' : 'src/libprs500/gui/main.py', 'dest_base':'prs500-gui', - 'icon_resources':[(1,'icons/library.ico')]}] - options = { 'py2exe' : {'includes': ['sip', 'pkg_resources'], 'dist_dir':'c:\libprs500', - 'packages' : ['PIL']}} -except ImportError: - console, windows, options = [], [], {} -finally: - library = 'libprs500_lib.zip' +from setuptools import setup, find_packages + +py2exe_options = {} +if sys.argv[1] == 'py2exe': + py2exe_dir = 'C:\libprs500' + f = open('installer.nsi', 'r+') + src = f.read() + f.seek(0) + src = re.sub('(define PRODUCT_VERSION).*', r'\1 "'+VERSION+'"', src) + src = re.sub('(define PY2EXE_DIR).*', r'\1 "'+py2exe_dir+'"', src) + f.write(src) + f.close() + try: + import py2exe + console = [{'script' : 'src/libprs500/cli/main.py', 'dest_base':'prs500'}] + windows = [{'script' : 'src/libprs500/gui/main.py', 'dest_base':'prs500-gui', + 'icon_resources':[(1,'icons/library.ico')]}] + excludes = ["Tkconstants", "Tkinter", "tcl", "_imagingtk", + "ImageTk", "FixTk"] + options = { 'py2exe' : {'includes' : ['sip', 'pkg_resources'], + 'dist_dir' : py2exe_dir, + 'packages' : ['PIL'], + 'excludes' : excludes}} + py2exe_options = {'console' : console, 'windows' : windows, + 'options' : options, 'excludes' : excludes} + except ImportError: + print >>sys.stderr, 'Must be in Windows to run py2exe' + sys.exit(1) + + # Try to install the Python imaging library as the package name (PIL) doesn't # match the distribution file name, thus declaring itas a dependency is useless @@ -49,10 +70,6 @@ except Exception, e: "Some functionality will be unavailable" -from setuptools import setup, find_packages -sys.path.append('src') -from libprs500 import __version__ as VERSION - if sys.hexversion < 0x2050000: print >> sys.stderr, "You must use python >= 2.5 Try invoking this script as python2.5 setup.py." print >> sys.stderr, "If you are using easy_install, try easy_install-2.5" @@ -83,11 +100,7 @@ setup( ], 'gui_scripts' : [ 'prs500-gui = libprs500.gui.main:main'] }, - zip_safe = True, - console = console, - windows = windows, - options = options, - library = library, + zip_safe = True, description = """ Library to interface with the Sony Portable Reader 500 @@ -108,6 +121,8 @@ setup( from LRF files (unencrypted books in the SONY BBeB format). A command line interface to this is provided via the command lrf-meta. + A windows installer is available from https://libprs500.kovidgoyal.net + For SVN access: svn co https://svn.kovidgoyal.net/code/libprs500 .. _SONY Portable Reader: http://Sony.com/reader @@ -126,7 +141,8 @@ setup( 'Programming Language :: Python', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: System :: Hardware :: Hardware Drivers' - ] + ], + **py2exe_options ) try: @@ -135,6 +151,6 @@ except ImportError: print "You do not have PyQt4 installed. The GUI will not work.", \ "You can obtain PyQt4 from http://www.riverbankcomputing.co.uk/pyqt/download.php" else: - import PyQt4.Qt - if PyQt4.Qt.PYQT_VERSION < 0x40101: + import PyQt4.QtCore + if PyQt4.QtCore.PYQT_VERSION < 0x40101: print "WARNING: The GUI needs PyQt >= 4.1.1" diff --git a/src/libprs500/__init__.py b/src/libprs500/__init__.py index 8e99e729a1..47bdfc025c 100644 --- a/src/libprs500/__init__.py +++ b/src/libprs500/__init__.py @@ -33,7 +33,7 @@ You may have to adjust the GROUP and the location of the rules file to suit your distribution. """ -__version__ = "0.3.11" +__version__ = "0.3.12" __docformat__ = "epytext" __author__ = "Kovid Goyal " diff --git a/src/libprs500/gui/main.py b/src/libprs500/gui/main.py index b20b31b2ed..9f7366bc2e 100644 --- a/src/libprs500/gui/main.py +++ b/src/libprs500/gui/main.py @@ -35,6 +35,7 @@ from libprs500.gui.widgets import LibraryBooksModel, DeviceBooksModel, \ from libprs500.gui.main_ui import Ui_MainWindow from libprs500.gui.database import LibraryDatabase from libprs500.gui.editbook import EditBookDialog +from libprs500 import __version__ as VERSION DEFAULT_BOOK_COVER = None @@ -479,7 +480,7 @@ class Main(QObject, Ui_MainWindow): self.device_removed) self.search.setFocus(Qt.OtherFocusReason) self.show_device(False) - self.df_template = self.df.text() + self.df_template = self.df.text().arg(VERSION) self.df.setText(self.df_template.arg("").arg("").arg("")) window.show() self.library_view.resizeColumnsToContents() diff --git a/src/libprs500/gui/main.ui b/src/libprs500/gui/main.ui index 9e7bf4e0e2..2ca87211ea 100644 --- a/src/libprs500/gui/main.ui +++ b/src/libprs500/gui/main.ui @@ -93,7 +93,7 @@ - For help visit <a href="https://libprs500.kovidgoyal.net/wiki/GuiUsage">http://libprs500.kovidgoyal.net</a><br><br><b>libprs500</b> was created by <b>Kovid Goyal</b> &copy; 2006<br>%1 %2 %3 + For help visit <a href="https://libprs500.kovidgoyal.net/wiki/GuiUsage">http://libprs500.kovidgoyal.net</a><br><br><b>libprs500</b>: %1 by <b>Kovid Goyal</b> &copy; 2006<br>%2 %3 %4 Qt::RichText @@ -287,8 +287,8 @@ - 124 - 50 + 163 + 58 @@ -354,16 +354,6 @@ - - LibraryBooksView - QTableView -
widgets.h
-
- - DeviceBooksView - QTableView -
widgets.h
-
CoverDisplay QLabel @@ -374,6 +364,16 @@ QListView
widgets.h
+ + LibraryBooksView + QTableView +
widgets.h
+
+ + DeviceBooksView + QTableView +
widgets.h
+
diff --git a/src/libprs500/gui/main_ui.py b/src/libprs500/gui/main_ui.py index 4191ae2716..24a3b1fc60 100644 --- a/src/libprs500/gui/main_ui.py +++ b/src/libprs500/gui/main_ui.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -# Form implementation generated from reading ui file 'main.ui' +# Form implementation generated from reading ui file 'src/libprs500/gui/main.ui' # -# Created: Mon Apr 9 18:48:38 2007 +# Created: Tue Apr 17 19:56:30 2007 # by: PyQt4 UI code generator 4.1.1 # # WARNING! All changes made in this file will be lost! @@ -154,7 +154,7 @@ class Ui_MainWindow(object): MainWindow.setCentralWidget(self.centralwidget) self.tool_bar = QtGui.QToolBar(MainWindow) - self.tool_bar.setMinimumSize(QtCore.QSize(124,50)) + self.tool_bar.setMinimumSize(QtCore.QSize(163,58)) self.tool_bar.setMovable(False) self.tool_bar.setOrientation(QtCore.Qt.Horizontal) self.tool_bar.setIconSize(QtCore.QSize(22,22)) @@ -185,7 +185,7 @@ class Ui_MainWindow(object): QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): - self.df.setText(QtGui.QApplication.translate("MainWindow", "For help visit http://libprs500.kovidgoyal.net

libprs500 was created by Kovid Goyal © 2006
%1 %2 %3", None, QtGui.QApplication.UnicodeUTF8)) + self.df.setText(QtGui.QApplication.translate("MainWindow", "For help visit http://libprs500.kovidgoyal.net

libprs500: %1 by Kovid Goyal © 2006
%2 %3 %4", None, QtGui.QApplication.UnicodeUTF8)) self.label.setText(QtGui.QApplication.translate("MainWindow", "&Search:", None, QtGui.QApplication.UnicodeUTF8)) self.search.setToolTip(QtGui.QApplication.translate("MainWindow", "Search the list of books by title or author

Words separated by spaces are ANDed", None, QtGui.QApplication.UnicodeUTF8)) self.search.setWhatsThis(QtGui.QApplication.translate("MainWindow", "Search the list of books by title or author

Words separated by spaces are ANDed", None, QtGui.QApplication.UnicodeUTF8)) diff --git a/src/libprs500/lrf/makelrf.py b/src/libprs500/lrf/makelrf.py index d5123d197a..3f14532837 100755 --- a/src/libprs500/lrf/makelrf.py +++ b/src/libprs500/lrf/makelrf.py @@ -33,7 +33,7 @@ _bbebook = 'BBeBook-0.2.jar' def generate_thumbnail(path): """ Generate a JPEG thumbnail of size ~ 128x128 (aspect ratio preserved)""" try: - import Image + from PIL import Image except ImportError: raise LRFException("Unable to initialize Python Imaging Library." \ "Thumbnail generation is disabled")