GwR wip tweak_epub

This commit is contained in:
GRiker 2010-09-20 06:06:00 -07:00
commit 58fa93c903
8 changed files with 321 additions and 15 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,59 @@
import re
from calibre.web.feeds.news import BasicNewsRecipe
class AdvancedUserRecipe1282101454(BasicNewsRecipe):
title = 'Popular Science'
language = 'en'
__author__ = 'TonytheBookworm'
description = 'Popular Science'
publisher = 'Popular Science'
category = 'gadgets,science'
oldest_article = 7 # change this if you want more current articles. I like to go a week in
max_articles_per_feed = 100
no_stylesheets = True
remove_javascript = True
masthead_url = 'http://www.raytheon.com/newsroom/rtnwcm/groups/Public/documents/masthead/rtn08_popscidec_masthead.jpg'
remove_tags = [dict(name='div', attrs={'id':['toolbar','main_supplements']}),
dict(name='span', attrs={'class':['comments']}),
dict(name='div', attrs={'class':['relatedinfo related-right','node_navigation','content2']}),
dict(name='ul', attrs={'class':['item-list clear-block']})]
feeds = [
('Gadgets', 'http://www.popsci.com/full-feed/gadgets'),
('Cars', 'http://www.popsci.com/full-feed/cars'),
('Science', 'http://www.popsci.com/full-feed/science'),
('Technology', 'http://www.popsci.com/full-feed/technology'),
('DIY', 'http://www.popsci.com/full-feed/diy'),
]
#The following will get read of the Gallery: links when found
def preprocess_html(self, soup) :
print 'SOUP IS: ', soup
weblinks = soup.findAll(['head','h2'])
if weblinks is not None:
for link in weblinks:
if re.search('(Gallery)(:)',str(link)):
link.parent.extract()
return soup
#-----------------------------------------------------------------

View File

@ -176,6 +176,7 @@ def get_metadata(stream, extract_cover=True):
except:
import traceback
traceback.print_exc()
mi.timestamp = None
return mi
def get_quick_metadata(stream):

View File

@ -39,7 +39,7 @@ gprefs.defaults['action-layout-context-menu'] = (
'Edit Metadata', 'Send To Device', 'Save To Disk',
'Connect Share', 'Copy To Library', None,
'Convert Books', 'View', 'Open Folder', 'Show Book Details',
'Similar Books', None, 'Remove Books',
'Similar Books', 'Tweak ePub', None, 'Remove Books',
)
gprefs.defaults['action-layout-context-menu-device'] = (

View File

@ -5,30 +5,61 @@ __license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
from calibre.constants import iswindows, isosx
from calibre.gui2 import error_dialog
from calibre.gui2.actions import InterfaceAction
from calibre.gui2.dialogs.tweak_epub import TweakEpub
class TweakEpubAction(InterfaceAction):
name = 'Tweak ePub'
action_spec = (_('Edit ePub in situ'), 'document_open.png', None, None)
#dont_add_to = frozenset(['toolbar-device', 'context-menu-device'])
action_spec = (_('Tweak ePub'), 'tweak_epub.png', 'Edit ePub in situ',
_('T'))
dont_add_to = frozenset(['toolbar-device', 'context-menu-device'])
action_type = 'current'
def genesis(self):
self.qaction.triggered.connect(self.edit_epub_in_situ)
print "gui2.actions.tweak_epub:TweakEpubAction.genesis()"
self.qaction.triggered.connect(self._edit_epub_in_situ)
def initialization_complete(self):
print "gui2.actions.tweak_epub:TweakEpubAction.initialization_complete()"
def _edit_epub_in_situ(self, *args):
def library_changed(self, db):
print "gui2.actions.tweak_epub:TweakEpubAction.library_changed()"
# Assure exactly one row selected
rows = self.gui.library_view.selectionModel().selectedRows()
if not rows or len(rows) == 0:
d = error_dialog(self.gui, _('Cannot tweak ePub'), _('No book selected'))
d.exec_()
return
if len(rows) > 1:
d = error_dialog(self.gui, _('Cannot tweak ePub'), _('Multiple books selected'))
d.exec_()
return
def location_selected(self, loc):
print "gui2.actions.tweak_epub:TweakEpubAction.location_selected()"
# Confirm 'EPUB' in formats
row = rows[0].row()
formats = self.gui.library_view.model().db.formats(row).upper().split(',')
if not 'EPUB' in formats:
d = error_dialog(self.gui, _('Cannot tweak ePub'), _('No EPUB available'))
d.exec_()
return
def shutting_down(self):
print "gui2.actions.tweak_epub:TweakEpubAction.shutting_down()"
path_to_epub = self.gui.library_view.model().db.format_abspath(row, 'EPUB')
id = self._get_selected_id()
# Launch a modal dialog waiting for user to complete or cancel
dlg = TweakEpub(self.gui, path_to_epub)
if dlg.exec_() == dlg.Accepted:
self._update_db(id, dlg._output)
dlg.cleanup()
def _get_selected_id(self):
rows = self.gui.library_view.selectionModel().selectedRows()
return map(self.gui.library_view.model().id, rows)[0]
def _update_db(self, id, rebuilt):
'''
Update the calibre db with the tweaked epub
'''
print "gui2.actions.tweak_epub:TweakEpubAction._update_db()"
print " updating id %d from %s" % (id, rebuilt)
self.gui.library_view.model().db.add_format_with_hooks(id, 'EPUB', rebuilt, index_is_id=True)
def edit_epub_in_situ(self, *args):
print "gui2.actions.tweak_epub:TweakEpubAction.edit_epub_in_situ()"

View File

@ -0,0 +1,129 @@
#!/usr/bin/env python
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
from __future__ import with_statement
__license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import os, shutil, subprocess, sys
from contextlib import closing
from zipfile import ZipFile, ZIP_DEFLATED, ZIP_STORED
from PyQt4 import QtGui
from PyQt4.Qt import QDialog, SIGNAL
from calibre import prints
from calibre.constants import iswindows, isosx, DEBUG
from calibre.gui2.dialogs.tweak_epub_ui import Ui_Dialog
from calibre.libunzip import extract as zipextract
from calibre.ptempfile import PersistentTemporaryDirectory
class TweakEpub(QDialog, Ui_Dialog):
'''
Display controls for tweaking ePubs
To do:
- need way to kill file browser proc in cleanup()
- Windows file browser launch
- linux file browser launch
'''
def __init__(self, parent, epub):
QDialog.__init__(self, parent)
self._epub = epub
self._exploded = None
self._file_browser_proc = None
self._output = None
# Run the dialog setup generated from tweak_epub.ui
self.setupUi(self)
self.connect(self.cancel_button,
SIGNAL("clicked()"),
self.cancel)
self.connect(self.explode_button,
SIGNAL("clicked()"),
self.explode)
self.connect(self.rebuild_button,
SIGNAL("clicked()"),
self.rebuild)
# Position update dialog overlaying top left of app window
parent_loc = parent.pos()
self.move(parent_loc.x(),parent_loc.y())
def cancel(self):
if DEBUG:
prints("gui2.dialogs.tweak_epub:TweakEpub.cancel()")
return QDialog.reject(self)
def cleanup(self):
'''
Kill the file browser
'''
if DEBUG:
prints("gui2.dialogs.tweak_epub:TweakEpub.cleanup()")
# Kill file browser proc
if self._file_browser_proc:
if DEBUG:
prints(" killing file browser proc")
#self._file_browser_proc.terminate()
#self._file_browser_proc.kill()
#self._file_browser_send_signal()
#self._file_browser_proc = None
# Delete directory containing exploded ePub
if self._exploded is not None:
if DEBUG:
prints(" removing exploded dir\n %s" % self._exploded)
shutil.rmtree(self._exploded, ignore_errors=True)
def display_exploded(self):
'''
Generic subprocess launch of native file browser
User can use right-click to 'Open with ...'
'''
if DEBUG:
prints("gui2.dialogs.tweak_epub:TweakEpub.display_exploded()")
if isosx:
cmd = 'open %s' % self._exploded
elif iswindows:
cmd = 'start explorer.exe /e,/root,%s' % self._exploded
else:
cmd = '<linux command to open native file browser>'
# *** Kovid - need a way of launching this process than can be killed in cleanup() ***
self._file_browser_proc = subprocess.Popen(cmd, shell=True)
def explode(self):
if DEBUG:
prints("gui2.dialogs.tweak_epub:TweakEpub.explode()")
if self._exploded is None:
if DEBUG:
prints(" exploding %s" % self._epub)
self._exploded = PersistentTemporaryDirectory("_exploded", prefix='')
zipextract(self._epub, self._exploded)
self.display_exploded()
self.rebuild_button.setEnabled(True)
def rebuild(self):
if DEBUG:
prints("gui2.dialogs.tweak_epub:TweakEpub.rebuild()")
self._output = os.path.join(self._exploded, 'rebuilt.epub')
with closing(ZipFile(self._output, 'w', compression=ZIP_DEFLATED)) as zf:
# Write mimetype
zf.write(os.path.join(self._exploded,'mimetype'), 'mimetype', compress_type=ZIP_STORED)
# Write everything else
exclude_files = ['.DS_Store','mimetype','iTunesMetadata.plist']
for root, dirs, files in os.walk(self._exploded):
for fn in files:
if fn in exclude_files:
continue
absfn = os.path.join(root, fn)
zfn = absfn[len(self._exploded) + len(os.sep):]
zf.write(absfn, zfn)
return QDialog.accept(self)

View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>161</width>
<height>132</height>
</rect>
</property>
<property name="windowTitle">
<string>Tweak ePub</string>
</property>
<property name="sizeGripEnabled">
<bool>false</bool>
</property>
<property name="modal">
<bool>false</bool>
</property>
<widget class="QWidget" name="verticalLayoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>141</width>
<height>110</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="explode_button">
<property name="statusTip">
<string>Display contents of exploded ePub</string>
</property>
<property name="text">
<string>Explode ePub</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="rebuild_button">
<property name="enabled">
<bool>false</bool>
</property>
<property name="statusTip">
<string>Rebuild ePub from exploded contents</string>
</property>
<property name="text">
<string>Rebuild ePub</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="cancel_button">
<property name="statusTip">
<string>Discard changes</string>
</property>
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>