Pull from driver-dev

This commit is contained in:
Kovid Goyal 2009-06-05 08:42:55 -07:00
commit 1b52e46586
16 changed files with 425 additions and 349 deletions

View File

@ -67,11 +67,19 @@ class DevicePlugin(Plugin):
For example: For devices that present themselves as USB Mass storage For example: For devices that present themselves as USB Mass storage
devices, this method would be responsible for mounting the device or devices, this method would be responsible for mounting the device or
if the device has been automounted, for finding out where it has been if the device has been automounted, for finding out where it has been
mounted. The driver for the PRS505 has a implementation of this function mounted. The base class within USBMS device.py has a implementation of
that should serve as a good example for USB Mass storage devices. this function that should serve as a good example for USB Mass storage
devices.
''' '''
raise NotImplementedError() raise NotImplementedError()
def eject(self):
'''
Un-mount / eject the device from the OS. This does not check if there
are pending GUI jobs that need to communicate with the device.
'''
raise NotImplementedError()
def set_progress_reporter(self, report_progress): def set_progress_reporter(self, report_progress):
''' '''
@param report_progress: Function that is called with a % progress @param report_progress: Function that is called with a % progress

View File

@ -279,6 +279,9 @@ class PRS500(DeviceConfig, DevicePlugin):
if res.code != 0: if res.code != 0:
raise ProtocolError("Could not set time on device") raise ProtocolError("Could not set time on device")
def eject(self):
pass
def close(self): def close(self):
""" Release device interface """ """ Release device interface """
try: try:

View File

@ -491,3 +491,39 @@ class Device(DeviceConfig, DevicePlugin):
time.sleep(3) time.sleep(3)
self.open_osx() self.open_osx()
def eject_windows(self):
pass
def eject_osx(self):
pass
def eject_linux(self):
drives = self.find_device_nodes()
for drive in drives:
if drive:
cmd = ['pumount']
try:
p = subprocess.Popen(cmd + [drive])
except:
pass
while p.poll() is None:
time.sleep(0.1)
def eject(self):
if islinux:
try:
self.eject_linux()
except:
pass
if iswindows:
try:
self.eject_windows()
except:
pass
if isosx:
try:
self.eject_osx()
except:
pass
self._main_prefix = self._card_a_prefix = self._card_b_prefix = None

View File

@ -1,312 +0,0 @@
# -*- coding: utf-8 -*-
'''
Maping of non-acii symbols and their corresponding html entity number and name
'''
__license__ = 'GPL v3'
__copyright__ = '2009, John Schember <john@nachtimwald.com>'
# http://www.w3schools.com/tags/ref_symbols.asp
HTML_SYMBOLS = {
# Math Symbols
u'' : ['&#8704;', '&forall;'], # for all
u'' : ['&#8706;', '&part;'], # part
u'' : ['&#8707;', '&exists;'], # exists
u'' : ['&#8709;', '&empty;'], # empty
u'' : ['&#8711;', '&nabla;'], # nabla
u'' : ['&#8712;', '&isin;'], # isin
u'' : ['&#8713;', '&notin;'], # notin
u'' : ['&#8715;', '&ni;'], # ni
u'' : ['&#8719;', '&prod;'], # prod
u'' : ['&#8721;', '&sum;'], # sum
u'' : ['&#8722;', '&minus;'], # minus
u'' : ['&#8727;', '&lowast;'], # lowast
u'' : ['&#8730;', '&radic;'], # square root
u'' : ['&#8733;', '&prop;'], # proportional to
u'' : ['&#8734;', '&infin;'], # infinity
u'' : ['&#8736;', '&ang;'], # angle
u'' : ['&#8743;', '&and;'], # and
u'' : ['&#8744;', '&or;'], # or
u'' : ['&#8745;', '&cap;'], # cap
u'' : ['&#8746;', '&cup;'], # cup
u'' : ['&#8747;', '&int;'], # integral
u'' : ['&#8756;', '&there4;'], # therefore
u'' : ['&#8764;', '&sim;'], # simular to
u'' : ['&#8773;', '&cong;'], # approximately equal
u'' : ['&#8776;', '&asymp;'], # almost equal
u'' : ['&#8800;', '&ne;'], # not equal
u'' : ['&#8801;', '&equiv;'], # equivalent
u'' : ['&#8804;', '&le;'], # less or equal
u'' : ['&#8805;', '&ge;'], # greater or equal
u'' : ['&#8834;', '&sub;'], # subset of
u'' : ['&#8835;', '&sup;'], # superset of
u'' : ['&#8836;', '&nsub;'], # not subset of
u'' : ['&#8838;', '&sube;'], # subset or equal
u'' : ['&#8839;', '&supe;'], # superset or equal
u'' : ['&#8853;', '&oplus;'], # circled plus
u'' : ['&#8855;', '&otimes;'], # cirled times
u'' : ['&#8869;', '&perp;'], # perpendicular
u'' : ['&#8901;', '&sdot;'], # dot operator
# Greek Letters
u'Α' : ['&#913;', '&Alpha;'], # Alpha
u'Β' : ['&#914;', '&Beta;'], # Beta
u'Γ' : ['&#915;', '&Gamma;'], # Gamma
u'Δ' : ['&#916;', '&Delta;'], # Delta
u'Ε' : ['&#917;', '&Epsilon;'], # Epsilon
u'Ζ' : ['&#918;', '&Zeta;'], # Zeta
u'Η' : ['&#919;', '&Eta;'], # Eta
u'Θ' : ['&#920;', '&Theta;'], # Theta
u'Ι' : ['&#921;', '&Iota;'], # Iota
u'Κ' : ['&#922;', '&Kappa;'], # Kappa
u'Λ' : ['&#923;', '&Lambda;'], # Lambda
u'Μ' : ['&#924;', '&Mu;'], # Mu
u'Ν' : ['&#925;', '&Nu;'], # Nu
u'Ξ' : ['&#926;', '&Xi;'], # Xi
u'Ο' : ['&#927;', '&Omicron;'], # Omicron
u'Π' : ['&#928;', '&Pi;'], # Pi
u'Ρ' : ['&#929;', '&Rho;'], # Rho
u'Σ' : ['&#931;', '&Sigma;'], # Sigma
u'Τ' : ['&#932;', '&Tau;'], # Tau
u'Υ' : ['&#933;', '&Upsilon;'], # Upsilon
u'Φ' : ['&#934;', '&Phi;'], # Phi
u'Χ' : ['&#935;', '&Chi;'], # Chi
u'Ψ' : ['&#936;', '&Psi;'], # Psi
u'ω' : ['&#969;', '&omega;'], # omega
u'ϑ' : ['&#977;', '&thetasym;'], # theta symbol
u'ϒ' : ['&#978;', '&upsih;'], # upsilon symbol
u'ϖ' : ['&#982;', '&piv;'], # pi symbol
# Other
u'Œ' : ['&#338;', '&OElig;'], # capital ligature OE
u'œ' : ['&#339;', '&oelig;'], # small ligature oe
u'Š' : ['&#352;', '&Scaron;'], # capital S with caron
u'š' : ['&#353;', '&scaron;'], # small S with caron
u'Ÿ' : ['&#376;', '&Yuml;'], # capital Y with diaeres
u'ƒ' : ['&#402;', '&fnof;'], # f with hook
u'ˆ' : ['&#710;', '&circ;'], # modifier letter circumflex accent
u'˜' : ['&#732;', '&tilde;'], # small tilde
u'' : ['&#8211;', '&ndash;'], # en dash
u'' : ['&#8212;', '&mdash;'], # em dash
u'' : ['&#8216;', '&lsquo;'], # left single quotation mark
u'' : ['&#8217;', '&rsquo;'], # right single quotation mark
u'' : ['&#8218;', '&sbquo;'], # single low-9 quotation mark
u'' : ['&#8220;', '&ldquo;'], # left double quotation mark
u'' : ['&#8221;', '&rdquo;'], # right double quotation mark
u'' : ['&#8222;', '&bdquo;'], # double low-9 quotation mark
u'' : ['&#8224;', '&dagger;'], # dagger
u'' : ['&#8225;', '&Dagger;'], # double dagger
u'' : ['&#8226;', '&bull;'], # bullet
u'' : ['&#8230;', '&hellip;'], # horizontal ellipsis
u'' : ['&#8240;', '&permil;'], # per mille
u'' : ['&#8242;', '&prime;'], # minutes
u'' : ['&#8243;', '&Prime;'], # seconds
u'' : ['&#8249;', '&lsaquo;'], # single left angle quotation
u'' : ['&#8250;', '&rsaquo;'], # single right angle quotation
u'' : ['&#8254;', '&oline;'], # overline
u'' : ['&#8364;', '&euro;'], # euro
u'' : ['&#8482;', '&trade;'], # trademark
u'' : ['&#8592;', '&larr;'], # left arrow
u'' : ['&#8593;', '&uarr;'], # up arrow
u'' : ['&#8594;', '&rarr;'], # right arrow
u'' : ['&#8595;', '&darr;'], # down arrow
u'' : ['&#8596;', '&harr;'], # left right arrow
u'' : ['&#8629;', '&crarr;'], # carriage return arrow
u'' : ['&#8968;', '&lceil;'], # left ceiling
u'' : ['&#8969;', '&rceil;'], # right ceiling
u'' : ['&#8970;', '&lfloor;'], # left floor
u'' : ['&#8971;', '&rfloor;'], # right floor
u'' : ['&#9674;', '&loz;'], # lozenge
u'' : ['&#9824;', '&spades;'], # spade
u'' : ['&#9827;', '&clubs;'], # club
u'' : ['&#9829;', '&hearts;'], # heart
u'' : ['&#9830;', '&diams;'], # diamond
# Extra http://www.ascii.cl/htmlcodes.htm
u' ' : ['&#32;'], # space
u'!' : ['&#33;'], # exclamation point
u'#' : ['&#35;'], # number sign
u'$' : ['&#36;'], # dollar sign
u'%' : ['&#37;'], # percent sign
u'\'' : ['&#39;'], # single quote
u'(' : ['&#40;'], # opening parenthesis
u')' : ['&#41;'], # closing parenthesis
u'*' : ['&#42;'], # asterisk
u'+' : ['&#43;'], # plus sign
u',' : ['&#44;'], # comma
u'-' : ['&#45;'], # minus sign - hyphen
u'.' : ['&#46;'], # period
u'/' : ['&#47;'], # slash
u'0' : ['&#48;'], # zero
u'1' : ['&#49;'], # one
u'2' : ['&#50;'], # two
u'3' : ['&#51;'], # three
u'4' : ['&#52;'], # four
u'5' : ['&#53;'], # five
u'6' : ['&#54;'], # six
u'7' : ['&#55;'], # seven
u'8' : ['&#56;'], # eight
u'9' : ['&#57;'], # nine
u':' : ['&#58;'], # colon
u';' : ['&#59;'], # semicolon
u'=' : ['&#61;'], # equal sign
u'?' : ['&#63;'], # question mark
u'@' : ['&#64;'], # at symbol
u'A' : ['&#65;'], #
u'B' : ['&#66;'], #
u'C' : ['&#67;'], #
u'D' : ['&#68;'], #
u'E' : ['&#69;'], #
u'F' : ['&#70;'], #
u'G' : ['&#71;'], #
u'H' : ['&#72;'], #
u'I' : ['&#73;'], #
u'J' : ['&#74;'], #
u'K' : ['&#75;'], #
u'L' : ['&#76;'], #
u'M' : ['&#77;'], #
u'N' : ['&#78;'], #
u'O' : ['&#79;'], #
u'P' : ['&#80;'], #
u'Q' : ['&#81;'], #
u'R' : ['&#82;'], #
u'S' : ['&#83;'], #
u'T' : ['&#84;'], #
u'U' : ['&#85;'], #
u'V' : ['&#86;'], #
u'W' : ['&#87;'], #
u'X' : ['&#88;'], #
u'Y' : ['&#89;'], #
u'Z' : ['&#90;'], #
u'[' : ['&#91;'], # opening bracket
u'\\' : ['&#92;'], # backslash
u']' : ['&#93;'], # closing bracket
u'^' : ['&#94;'], # caret - circumflex
u'_' : ['&#95;'], # underscore
u'`' : ['&#96;'], # grave accent
u'a' : ['&#97;'], #
u'b' : ['&#98;'], #
u'c' : ['&#99;'], #
u'd' : ['&#100;'], #
u'e' : ['&#101;'], #
u'f' : ['&#102;'], #
u'g' : ['&#103;'], #
u'h' : ['&#104;'], #
u'i' : ['&#105;'], #
u'j' : ['&#106;'], #
u'k' : ['&#107;'], #
u'l' : ['&#108;'], #
u'm' : ['&#109;'], #
u'n' : ['&#110;'], #
u'o' : ['&#111;'], #
u'p' : ['&#112;'], #
u'q' : ['&#113;'], #
u'r' : ['&#114;'], #
u's' : ['&#115;'], #
u't' : ['&#116;'], #
u'u' : ['&#117;'], #
u'v' : ['&#118;'], #
u'w' : ['&#119;'], #
u'x' : ['&#120;'], #
u'y' : ['&#121;'], #
u'z' : ['&#122;'], #
u'{' : ['&#123;'], # opening brace
u'|' : ['&#124;'], # vertical bar
u'}' : ['&#125;'], # closing brace
u'~' : ['&#126;'], # equivalency sign - tilde
u'<' : ['&#60;', '&lt;'], # less than sign
u'>' : ['&#62;', '&gt;'], # greater than sign
u'¡' : ['&#161;', '&iexcl;'], # inverted exclamation mark
u'¢' : ['&#162;', '&cent;'], # cent sign
u'£' : ['&#163;', '&pound;'], # pound sign
u'¤' : ['&#164;', '&curren;'], # currency sign
u'¥' : ['&#165;', '&yen;'], # yen sign
u'¦' : ['&#166;', '&brvbar;'], # broken vertical bar
u'§' : ['&#167;', '&sect;'], # section sign
u'¨' : ['&#168;', '&uml;'], # spacing diaeresis - umlaut
u'©' : ['&#169;', '&copy;'], # copyright sign
u'ª' : ['&#170;', '&ordf;'], # feminine ordinal indicator
u'«' : ['&#171;', '&laquo;'], # left double angle quotes
u'¬' : ['&#172;', '&not;'], # not sign
u'®' : ['&#174;', '&reg;'], # registered trade mark sign
u'¯' : ['&#175;', '&macr;'], # spacing macron - overline
u'°' : ['&#176;', '&deg;'], # degree sign
u'±' : ['&#177;', '&plusmn;'], # plus-or-minus sign
u'²' : ['&#178;', '&sup2;'], # superscript two - squared
u'³' : ['&#179;', '&sup3;'], # superscript three - cubed
u'´' : ['&#180;', '&acute;'], # acute accent - spacing acute
u'µ' : ['&#181;', '&micro;'], # micro sign
u'' : ['&#182;', '&para;'], # pilcrow sign - paragraph sign
u'·' : ['&#183;', '&middot;'], # middle dot - Georgian comma
u'¸' : ['&#184;', '&cedil;'], # spacing cedilla
u'¹' : ['&#185;', '&sup1;'], # superscript one
u'º' : ['&#186;', '&ordm;'], # masculine ordinal indicator
u'»' : ['&#187;', '&raquo;'], # right double angle quotes
u'¼' : ['&#188;', '&frac14;'], # fraction one quarter
u'½' : ['&#189;', '&frac12;'], # fraction one half
u'¾' : ['&#190;', '&frac34;'], # fraction three quarters
u'¿' : ['&#191;', '&iquest;'], # inverted question mark
u'À' : ['&#192;', '&Agrave;'], # latin capital letter A with grave
u'Á' : ['&#193;', '&Aacute;'], # latin capital letter A with acute
u'Â' : ['&#194;', '&Acirc;'], # latin capital letter A with circumflex
u'Ã' : ['&#195;', '&Atilde;'], # latin capital letter A with tilde
u'Ä' : ['&#196;', '&Auml;'], # latin capital letter A with diaeresis
u'Å' : ['&#197;', '&Aring;'], # latin capital letter A with ring above
u'Æ' : ['&#198;', '&AElig;'], # latin capital letter AE
u'Ç' : ['&#199;', '&Ccedil;'], # latin capital letter C with cedilla
u'È' : ['&#200;', '&Egrave;'], # latin capital letter E with grave
u'É' : ['&#201;', '&Eacute;'], # latin capital letter E with acute
u'Ê' : ['&#202;', '&Ecirc;'], # latin capital letter E with circumflex
u'Ë' : ['&#203;', '&Euml;'], # latin capital letter E with diaeresis
u'Ì' : ['&#204;', '&Igrave;'], # latin capital letter I with grave
u'Í' : ['&#205;', '&Iacute;'], # latin capital letter I with acute
u'Î' : ['&#206;', '&Icirc;'], # latin capital letter I with circumflex
u'Ï' : ['&#207;', '&Iuml;'], # latin capital letter I with diaeresis
u'Ð' : ['&#208;', '&ETH;'], # latin capital letter ETH
u'Ñ' : ['&#209;', '&Ntilde;'], # latin capital letter N with tilde
u'Ò' : ['&#210;', '&Ograve;'], # latin capital letter O with grave
u'Ó' : ['&#211;', '&Oacute;'], # latin capital letter O with acute
u'Ô' : ['&#212;', '&Ocirc;'], # latin capital letter O with circumflex
u'Õ' : ['&#213;', '&Otilde;'], # latin capital letter O with tilde
u'Ö' : ['&#214;', '&Ouml;'], # latin capital letter O with diaeresis
u'×' : ['&#215;', '&times;'], # multiplication sign
u'Ø' : ['&#216;', '&Oslash;'], # latin capital letter O with slash
u'Ù' : ['&#217;', '&Ugrave;'], # latin capital letter U with grave
u'Ú' : ['&#218;', '&Uacute;'], # latin capital letter U with acute
u'Û' : ['&#219;', '&Ucirc;'], # latin capital letter U with circumflex
u'Ü' : ['&#220;', '&Uuml;'], # latin capital letter U with diaeresis
u'Ý' : ['&#221;', '&Yacute;'], # latin capital letter Y with acute
u'Þ' : ['&#222;', '&THORN;'], # latin capital letter THORN
u'ß' : ['&#223;', '&szlig;'], # latin small letter sharp s - ess-zed
u'à' : ['&#224;', '&agrave;'], # latin small letter a with grave
u'á' : ['&#225;', '&aacute;'], # latin small letter a with acute
u'â' : ['&#226;', '&acirc;'], # latin small letter a with circumflex
u'ã' : ['&#227;', '&atilde;'], # latin small letter a with tilde
u'ä' : ['&#228;', '&auml;'], # latin small letter a with diaeresis
u'å' : ['&#229;', '&aring;'], # latin small letter a with ring above
u'æ' : ['&#230;', '&aelig;'], # latin small letter ae
u'ç' : ['&#231;', '&ccedil;'], # latin small letter c with cedilla
u'è' : ['&#232;', '&egrave;'], # latin small letter e with grave
u'é' : ['&#233;', '&eacute;'], # latin small letter e with acute
u'ê' : ['&#234;', '&ecirc;'], # latin small letter e with circumflex
u'ë' : ['&#235;', '&euml;'], # latin small letter e with diaeresis
u'ì' : ['&#236;', '&igrave;'], # latin small letter i with grave
u'í' : ['&#237;', '&iacute;'], # latin small letter i with acute
u'î' : ['&#238;', '&icirc;'], # latin small letter i with circumflex
u'ï' : ['&#239;', '&iuml;'], # latin small letter i with diaeresis
u'ð' : ['&#240;', '&eth;'], # latin small letter eth
u'ñ' : ['&#241;', '&ntilde;'], # latin small letter n with tilde
u'ò' : ['&#242;', '&ograve;'], # latin small letter o with grave
u'ó' : ['&#243;', '&oacute;'], # latin small letter o with acute
u'ô' : ['&#244;', '&ocirc;'], # latin small letter o with circumflex
u'õ' : ['&#245;', '&otilde;'], # latin small letter o with tilde
u'ö' : ['&#246;', '&ouml;'], # latin small letter o with diaeresis
u'÷' : ['&#247;', '&divide;'], # division sign
u'ø' : ['&#248;', '&oslash;'], # latin small letter o with slash
u'ù' : ['&#249;', '&ugrave;'], # latin small letter u with grave
u'ú' : ['&#250;', '&uacute;'], # latin small letter u with acute
u'û' : ['&#251;', '&ucirc;'], # latin small letter u with circumflex
u'ü' : ['&#252;', '&uuml;'], # latin small letter u with diaeresis
u'ý' : ['&#253;', '&yacute;'], # latin small letter y with acute
u'þ' : ['&#254;', '&thorn;'], # latin small letter thorn
u'ÿ' : ['&#255;', '&yuml;'], # latin small letter y with diaeresis
# More
u' ' : ['&#160;'],
}

View File

@ -22,6 +22,11 @@ class PDBOutput(OutputFormatPlugin):
short_switch='f', choices=FORMAT_WRITERS.keys(), short_switch='f', choices=FORMAT_WRITERS.keys(),
help=(_('Format to use inside the pdb container. Choices are:')+\ help=(_('Format to use inside the pdb container. Choices are:')+\
' %s' % FORMAT_WRITERS.keys())), ' %s' % FORMAT_WRITERS.keys())),
OptionRecommendation(name='output_encoding', recommended_value='cp1252',
level=OptionRecommendation.LOW,
help=_('Specify the character encoding of the output document. ' \
'The default is cp1252. Note: This option is not honored by all ' \
'formats.')),
]) ])
def convert(self, oeb_book, output_path, input_plugin, opts, log): def convert(self, oeb_book, output_path, input_plugin, opts, log):

View File

@ -34,7 +34,7 @@ class Writer(FormatWriter):
self.log.info('Compessing data...') self.log.info('Compessing data...')
for i in range(0, len(txt_records)): for i in range(0, len(txt_records)):
self.log.debug('\tCompressing record %i' % i) self.log.debug('\tCompressing record %i' % i)
txt_records[i] = compress_doc(txt_records[i].encode('cp1252', 'replace')) txt_records[i] = compress_doc(txt_records[i])
section_lengths.append(len(txt_records[i])) section_lengths.append(len(txt_records[i]))
out_stream.seek(0) out_stream.seek(0)
@ -46,7 +46,7 @@ class Writer(FormatWriter):
def _generate_text(self, spine): def _generate_text(self, spine):
txt_writer = TxtWriter(TxtNewlines('system').newline, self.log) txt_writer = TxtWriter(TxtNewlines('system').newline, self.log)
txt = txt_writer.dump(spine) txt = txt_writer.dump(spine).encode(self.opts.output_encoding, 'replace')
txt_length = len(txt) txt_length = len(txt)

View File

@ -50,7 +50,7 @@ class Writer(FormatWriter):
def _generate_text(self, spine): def _generate_text(self, spine):
txt_writer = TxtWriter(TxtNewlines('system').newline, self.log) txt_writer = TxtWriter(TxtNewlines('system').newline, self.log)
txt = txt_writer.dump(spine) txt = txt_writer.dump(spine).encode(self.opts.output_encoding, 'replace')
txt_length = len(txt) txt_length = len(txt)

View File

@ -15,6 +15,7 @@ except ImportError:
import cStringIO import cStringIO
from calibre.customize.conversion import OutputFormatPlugin from calibre.customize.conversion import OutputFormatPlugin
from calibre.customize.conversion import OptionRecommendation
from calibre.ptempfile import TemporaryDirectory from calibre.ptempfile import TemporaryDirectory
from calibre.utils.zipfile import ZipFile from calibre.utils.zipfile import ZipFile
from calibre.ebooks.oeb.base import OEB_IMAGES from calibre.ebooks.oeb.base import OEB_IMAGES
@ -26,12 +27,20 @@ class PMLOutput(OutputFormatPlugin):
author = 'John Schember' author = 'John Schember'
file_type = 'pmlz' file_type = 'pmlz'
options = set([
OptionRecommendation(name='output_encoding', recommended_value='cp1252',
level=OptionRecommendation.LOW,
help=_('Specify the character encoding of the output document. ' \
'The default is cp1252. Note: This option is not honored by all ' \
'formats.')),
])
def convert(self, oeb_book, output_path, input_plugin, opts, log): def convert(self, oeb_book, output_path, input_plugin, opts, log):
with TemporaryDirectory('_pmlz_output') as tdir: with TemporaryDirectory('_pmlz_output') as tdir:
pmlmlizer = PMLMLizer(ignore_tables=opts.linearize_tables) pmlmlizer = PMLMLizer(ignore_tables=opts.linearize_tables)
content = pmlmlizer.extract_content(oeb_book, opts) content = pmlmlizer.extract_content(oeb_book, opts)
with open(os.path.join(tdir, 'index.pml'), 'wb') as out: with open(os.path.join(tdir, 'index.pml'), 'wb') as out:
out.write(content.encode('utf-8')) out.write(content.encode(self.opts.output_encoding, 'replace'))
self.write_images(oeb_book.manifest, tdir) self.write_images(oeb_book.manifest, tdir)

View File

@ -10,10 +10,9 @@ __docformat__ = 'restructuredtext en'
import re import re
from calibre.ebooks.pdb.ereader import image_name from htmlentitydefs import codepoint2name
from calibre.ebooks.htmlsymbols import HTML_SYMBOLS
from BeautifulSoup import BeautifulSoup from calibre.ebooks.pdb.ereader import image_name
PML_HTML_RULES = [ PML_HTML_RULES = [
(re.compile(r'\\p'), lambda match: '<br /><br style="page-break-after: always;" />'), (re.compile(r'\\p'), lambda match: '<br /><br style="page-break-after: always;" />'),
@ -71,10 +70,12 @@ def pml_to_html(pml):
for rule in PML_HTML_RULES: for rule in PML_HTML_RULES:
html = rule[0].sub(rule[1], html) html = rule[0].sub(rule[1], html)
for symbol in HTML_SYMBOLS.keys(): # Turn special characters into entities.
if ord(symbol) > 128: cps = [ord(c) for c in set(html)]
html = html.replace(symbol, HTML_SYMBOLS[symbol][len(HTML_SYMBOLS[symbol]) - 1]) cps = set(cps).intersection(codepoint2name.keys()).difference([60, 62])
for cp in cps:
html = html.replace(unichr(cp), '&%s;' % codepoint2name[cp])
return html return html
def footnote_sidebar_to_html(id, pml): def footnote_sidebar_to_html(id, pml):

View File

@ -17,13 +17,18 @@ class TXTOutput(OutputFormatPlugin):
file_type = 'txt' file_type = 'txt'
options = set([ options = set([
OptionRecommendation(name='newline', recommended_value='system', OptionRecommendation(name='newline', recommended_value='system',
level=OptionRecommendation.LOW, level=OptionRecommendation.LOW,
short_switch='n', choices=TxtNewlines.NEWLINE_TYPES.keys(), short_switch='n', choices=TxtNewlines.NEWLINE_TYPES.keys(),
help=_('Type of newline to use. Options are %s. Default is \'system\'. ' help=_('Type of newline to use. Options are %s. Default is \'system\'. '
'Use \'old_mac\' for compatibility with Mac OS 9 and earlier. ' 'Use \'old_mac\' for compatibility with Mac OS 9 and earlier. '
'For Mac OS X use \'unix\'. \'system\' will default to the newline ' 'For Mac OS X use \'unix\'. \'system\' will default to the newline '
'type used by this OS.') % sorted(TxtNewlines.NEWLINE_TYPES.keys())), 'type used by this OS.') % sorted(TxtNewlines.NEWLINE_TYPES.keys())),
OptionRecommendation(name='output_encoding', recommended_value='utf-8',
level=OptionRecommendation.LOW,
help=_('Specify the character encoding of the output document. ' \
'The default is utf-8. Note: This option is not honored by all ' \
'formats.')),
]) ])
def convert(self, oeb_book, output_path, input_plugin, opts, log): def convert(self, oeb_book, output_path, input_plugin, opts, log):
@ -41,7 +46,7 @@ class TXTOutput(OutputFormatPlugin):
out_stream.seek(0) out_stream.seek(0)
out_stream.truncate() out_stream.truncate()
out_stream.write(txt.encode('utf-8')) out_stream.write(txt.encode(self.opts.output_encoding, 'replace'))
if close: if close:
out_stream.close() out_stream.close()

View File

@ -12,7 +12,6 @@ import os
import re import re
from calibre import entity_to_unicode from calibre import entity_to_unicode
from calibre.ebooks.htmlsymbols import HTML_SYMBOLS
from BeautifulSoup import BeautifulSoup from BeautifulSoup import BeautifulSoup
@ -82,10 +81,6 @@ class TxtWriter(object):
return stripped return stripped
def replace_html_symbols(self, content): def replace_html_symbols(self, content):
for symbol in HTML_SYMBOLS:
for code in HTML_SYMBOLS[symbol]:
content = content.replace(code, symbol)
for entity in set(re.findall('&.+?;', content)): for entity in set(re.findall('&.+?;', content)):
mo = re.search('(%s)' % entity[1:-1], content) mo = re.search('(%s)' % entity[1:-1], content)
content = content.replace(entity, entity_to_unicode(mo)) content = content.replace(entity, entity_to_unicode(mo))

View File

@ -123,6 +123,10 @@ class DeviceManager(Thread):
self.connected_slot(False) self.connected_slot(False)
device[1] ^= True device[1] ^= True
def umount_device(self):
self.device.eject()
self.device = None
def next(self): def next(self):
if not self.jobs.empty(): if not self.jobs.empty():
try: try:
@ -852,5 +856,3 @@ class DeviceGUI(object):
getattr(f, 'close', lambda : True)() getattr(f, 'close', lambda : True)()
if memory and memory[1]: if memory and memory[1]:
self.library_view.model().delete_books_by_id(memory[1]) self.library_view.model().delete_books_by_id(memory[1])

View File

@ -0,0 +1,281 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="128"
height="128"
id="svg3186"
sodipodi:version="0.32"
inkscape:version="0.45"
version="1.0"
sodipodi:docname="player_end.svg"
sodipodi:docbase="/home/david/Progetti/sandbox"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
sodipodi:modified="true">
<defs
id="defs3188">
<radialGradient
inkscape:collect="always"
xlink:href="#radialGradient3163"
id="radialGradient2197"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(4.7377213e-8,-0.1315545,0.7519296,0,12.61245,94.56941)"
cx="80.342453"
cy="68.340897"
fx="80.342453"
fy="68.340897"
r="40.0294" />
<radialGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.6667,0,0,0.7574,20.7214,14.064)"
r="40.0294"
cy="59.1865"
cx="53.1978"
id="radialGradient3163">
<stop
id="stop3165"
style="stop-color:#000000;stop-opacity:1;"
offset="0" />
<stop
id="stop3175"
style="stop-color:#666666;stop-opacity:1;"
offset="1" />
</radialGradient>
<linearGradient
id="XMLID_9_"
gradientUnits="userSpaceOnUse"
x1="11.9487"
y1="34"
x2="104.0518"
y2="34"
gradientTransform="translate(559.14286,-264.28571)">
<stop
offset="0"
style="stop-color:#FFFFFF"
id="stop56" />
<stop
offset="0.80000001"
style="stop-color:#ffffff;stop-opacity:0;"
id="stop58" />
</linearGradient>
<radialGradient
id="XMLID_8_"
cx="53.1978"
cy="59.1865"
r="40.0294"
gradientTransform="matrix(0.6667,0,0,0.7574,20.7214,14.064)"
gradientUnits="userSpaceOnUse">
<stop
offset="0"
style="stop-color:#323232"
id="stop41" />
<stop
offset="0.2083"
style="stop-color:#363636"
id="stop43" />
<stop
offset="0.4278"
style="stop-color:#434343"
id="stop45" />
<stop
offset="0.6526"
style="stop-color:#585858"
id="stop47" />
<stop
offset="0.8796"
style="stop-color:#757575"
id="stop49" />
<stop
offset="1"
style="stop-color:#888888"
id="stop51" />
</radialGradient>
<radialGradient
id="XMLID_7_"
cx="58"
cy="58"
r="48"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(559.14286,-264.28571)">
<stop
offset="0"
style="stop-color:#FFFFFF"
id="stop26" />
<stop
offset="0.574"
style="stop-color:#FFFFFF"
id="stop28" />
<stop
offset="0.6842"
style="stop-color:#FBFBFB"
id="stop30" />
<stop
offset="0.8001"
style="stop-color:#EEEEEE"
id="stop32" />
<stop
offset="0.9"
style="stop-color:#DDDDDD"
id="stop34" />
<stop
offset="1"
style="stop-color:#BBBBBB"
id="stop36" />
</radialGradient>
<filter
id="AI_Sfocatura_4">
<feGaussianBlur
stdDeviation="4"
id="feGaussianBlur6" />
</filter>
<linearGradient
id="XMLID_6_"
gradientUnits="userSpaceOnUse"
x1="58.0005"
y1="116"
x2="58.0005"
y2="4.882812e-04">
<stop
offset="0"
style="stop-color:#555555"
id="stop9" />
<stop
offset="0.2736"
style="stop-color:#595959"
id="stop11" />
<stop
offset="0.562"
style="stop-color:#666666"
id="stop13" />
<stop
offset="0.8561"
style="stop-color:#7B7B7B"
id="stop15" />
<stop
offset="1"
style="stop-color:#888888"
id="stop17" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#XMLID_9_"
id="linearGradient3242"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(6.0000006,6.0000006)"
x1="11.9487"
y1="34"
x2="104.0518"
y2="34" />
<radialGradient
inkscape:collect="always"
xlink:href="#XMLID_7_"
id="radialGradient3246"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0833333,0,0,1.0833333,1.1666673,1.1666673)"
cx="58"
cy="58"
r="48" />
<linearGradient
inkscape:collect="always"
xlink:href="#XMLID_6_"
id="linearGradient3251"
gradientUnits="userSpaceOnUse"
x1="58.0005"
y1="116"
x2="58.0005"
y2="4.882812e-04" />
<radialGradient
inkscape:collect="always"
xlink:href="#radialGradient3163"
id="radialGradient3253"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.6667,0,0,0.7574,20.7214,14.064)"
cx="53.1978"
cy="59.186501"
r="40.0294" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8284271"
inkscape:cx="62"
inkscape:cy="44.566099"
inkscape:document-units="px"
inkscape:current-layer="layer1"
width="128px"
height="128px"
showgrid="true"
gridspacingx="8px"
gridspacingy="8px"
inkscape:window-width="792"
inkscape:window-height="581"
inkscape:window-x="225"
inkscape:window-y="112" />
<metadata
id="metadata3191">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<circle
cx="58"
cy="58"
r="58"
id="circle19"
style="fill:url(#linearGradient3251)"
sodipodi:cx="58"
sodipodi:cy="58"
sodipodi:rx="58"
sodipodi:ry="58"
transform="matrix(1.1034483,0,0,1.1034483,0,-2.8e-6)" />
<g
id="g21"
transform="matrix(1.0833333,0,0,1.0833333,1.1666686,1.1666686)"
style="filter:url(#AI_Sfocatura_4);opacity:0.8">
<path
d="M 10,58 C 10,84.467 31.533,106 58,106 C 84.467,106 106,84.467 106,58 C 106,31.533 84.467,10 58,10 C 31.533,10 10,31.533 10,58 z "
id="path23" />
</g>
<path
d="M 12,63.999999 C 12,92.672581 35.327414,116 63.999998,116 C 92.672584,116 116,92.672581 116,63.999999 C 116,35.327415 92.672584,12 63.999998,12 C 35.327414,12 12,35.327415 12,63.999999 z "
id="path38"
style="fill:url(#radialGradient3246)" />
<polygon
points="42,26 90,58 42,90 42,26 "
id="polygon53"
style="fill:url(#radialGradient3253);fill-opacity:1"
transform="matrix(0,-0.8333333,1,0,6,107)" />
<path
sodipodi:nodetypes="ccccc"
id="path2195"
d="M 40,88 L 40.38871,80 L 87.95798,80.005265 L 88,87.94911 L 40,88 z "
style="fill:url(#radialGradient2197);fill-opacity:1" />
<path
d="M 63.999998,63.999999 C 81.788999,63.999999 97.967006,58.87 110.05199,50.491 C 104.19999,30.582 85.775999,16 63.999998,16 C 42.222999,16 23.798999,30.582999 17.949,50.491 C 30.032,58.87 46.209999,63.999999 63.999998,63.999999 z "
id="path60"
style="opacity:0.5;fill:url(#linearGradient3242)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.0 KiB

View File

@ -176,10 +176,23 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
SIGNAL('activated(QSystemTrayIcon::ActivationReason)'), SIGNAL('activated(QSystemTrayIcon::ActivationReason)'),
self.system_tray_icon_activated) self.system_tray_icon_activated)
self.tool_bar.contextMenuEvent = self.no_op self.tool_bar.contextMenuEvent = self.no_op
####################### Start spare job server ########################
QTimer.singleShot(1000, self.add_spare_server)
####################### Setup device detection ########################
self.device_manager = DeviceManager(Dispatcher(self.device_detected),
self.job_manager)
self.device_manager.start()
####################### Location View ######################## ####################### Location View ########################
QObject.connect(self.location_view, QObject.connect(self.location_view,
SIGNAL('location_selected(PyQt_PyObject)'), SIGNAL('location_selected(PyQt_PyObject)'),
self.location_selected) self.location_selected)
QObject.connect(self.location_view,
SIGNAL('umount_device()'),
self.device_manager.umount_device)
####################### Vanity ######################## ####################### Vanity ########################
self.vanity_template = _('<p>For help visit <a href="http://%s.' self.vanity_template = _('<p>For help visit <a href="http://%s.'
@ -462,13 +475,6 @@ class Main(MainWindow, Ui_MainWindow, DeviceGUI):
self.setMaximumHeight(max_available_height()) self.setMaximumHeight(max_available_height())
####################### Start spare job server ########################
QTimer.singleShot(1000, self.add_spare_server)
####################### Setup device detection ########################
self.device_manager = DeviceManager(Dispatcher(self.device_detected),
self.job_manager)
self.device_manager.start()
if config['autolaunch_server']: if config['autolaunch_server']:

View File

@ -45,6 +45,9 @@
<height>75</height> <height>75</height>
</size> </size>
</property> </property>
<property name="mouseTracking">
<bool>true</bool>
</property>
<property name="verticalScrollBarPolicy"> <property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum> <enum>Qt::ScrollBarAlwaysOff</enum>
</property> </property>

View File

@ -9,7 +9,8 @@ from PyQt4.Qt import QListView, QIcon, QFont, QLabel, QListWidget, \
QSyntaxHighlighter, QCursor, QColor, QWidget, \ QSyntaxHighlighter, QCursor, QColor, QWidget, \
QPixmap, QMovie, QPalette, QTimer, QDialog, \ QPixmap, QMovie, QPalette, QTimer, QDialog, \
QAbstractListModel, QVariant, Qt, SIGNAL, \ QAbstractListModel, QVariant, Qt, SIGNAL, \
QRegExp, QSettings, QSize, QModelIndex QRegExp, QSettings, QSize, QModelIndex, \
QAbstractButton, QPainter
from calibre.gui2 import human_readable, NONE, TableView, \ from calibre.gui2 import human_readable, NONE, TableView, \
qstring_to_unicode, error_dialog qstring_to_unicode, error_dialog
@ -234,6 +235,13 @@ class LocationView(QListView):
self.setCursor(Qt.PointingHandCursor) self.setCursor(Qt.PointingHandCursor)
self.currentChanged = self.current_changed self.currentChanged = self.current_changed
self.eject_button = EjectButton(self)
self.eject_button.hide()
self.connect(self, SIGNAL('entered(QModelIndex)'), self.show_eject)
self.connect(self, SIGNAL('viewportEntered()'), self.hide_eject)
self.connect(self.eject_button, SIGNAL('clicked()'), lambda: self.emit(SIGNAL('umount_device()')))
def count_changed(self, new_count): def count_changed(self, new_count):
self.model().count = new_count self.model().count = new_count
self.model().reset() self.model().reset()
@ -249,6 +257,33 @@ class LocationView(QListView):
if 0 <= row and row <= 3: if 0 <= row and row <= 3:
self.model().location_changed(row) self.model().location_changed(row)
def show_eject(self, location):
self.eject_button.hide()
if location.row() == 1:
rect = self.visualRect(location)
self.eject_button.resize(rect.height()/2, rect.height()/2)
x, y = rect.left(), rect.top()
x = x + (rect.width() - self.eject_button.width() - 2)
y += 6
self.eject_button.move(x, y)
self.eject_button.show()
def hide_eject(self):
self.eject_button.hide()
class EjectButton(QAbstractButton):
def paintEvent(self, event):
painter = QPainter(self)
painter.setClipRect(event.rect());
painter.drawPixmap(0, 0, QPixmap(':/images/eject').scaledToHeight(event.rect().height(), Qt.SmoothTransformation))
class DetailView(QDialog, Ui_Dialog): class DetailView(QDialog, Ui_Dialog):
def __init__(self, parent, job): def __init__(self, parent, job):
@ -617,4 +652,3 @@ class PythonHighlighter(QSyntaxHighlighter):
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
QSyntaxHighlighter.rehighlight(self) QSyntaxHighlighter.rehighlight(self)
QApplication.restoreOverrideCursor() QApplication.restoreOverrideCursor()