From ee43ccb71e66e817d869f4819c12f5e519495c38 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 15 Feb 2010 16:46:55 -0700 Subject: [PATCH 1/4] Workaround for local timezones with historical dates on crippled commercial operating systems --- src/calibre/utils/date.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/calibre/utils/date.py b/src/calibre/utils/date.py index 8b26ab02bc..da5a2d3bc2 100644 --- a/src/calibre/utils/date.py +++ b/src/calibre/utils/date.py @@ -11,8 +11,17 @@ from datetime import datetime from dateutil.parser import parse from dateutil.tz import tzlocal, tzutc +class SafeLocalTimeZone(tzlocal): + + def _isdst(self, dt): + try: + return tzlocal._isdst(self, dt) + except ValueError: + pass + return False + utc_tz = _utc_tz = tzutc() -local_tz = _local_tz = tzlocal() +local_tz = _local_tz = SafeLocalTimeZone() def parse_date(date_string, assume_utc=False, as_utc=True, default=None): ''' From cc1c5bb6fdcf202adbb6773cee71c2348b023bfb Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 15 Feb 2010 16:54:47 -0700 Subject: [PATCH 2/4] ... --- src/calibre/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/calibre/__init__.py b/src/calibre/__init__.py index e5e284fb5b..0742e60229 100644 --- a/src/calibre/__init__.py +++ b/src/calibre/__init__.py @@ -378,10 +378,11 @@ def strftime(fmt, t=None): t = time.localtime() early_year = t[0] < 1900 if early_year: + replacement = 1900 if t[0]%4 == 0 else 1901 fmt = fmt.replace('%Y', '_early year hack##') t = list(t) orig_year = t[0] - t[0] = 1900 + t[0] = replacement ans = None if iswindows: if isinstance(fmt, unicode): From c187c899ca476dafb148cdca27564c5ec6cf2241 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 15 Feb 2010 16:56:33 -0700 Subject: [PATCH 3/4] ... --- src/calibre/utils/date.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/calibre/utils/date.py b/src/calibre/utils/date.py index da5a2d3bc2..9a433e3a6d 100644 --- a/src/calibre/utils/date.py +++ b/src/calibre/utils/date.py @@ -12,6 +12,10 @@ from dateutil.parser import parse from dateutil.tz import tzlocal, tzutc class SafeLocalTimeZone(tzlocal): + ''' + Assume DST was not in effect for historical dates, if DST + data for the local timezone is not present in the operating system. + ''' def _isdst(self, dt): try: From bd350e57cea4656f1a2bc0f8b34c6590ab95ab34 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 15 Feb 2010 17:31:16 -0700 Subject: [PATCH 4/4] Update bundled odfpy --- src/odf/element.py | 21 +++++++++++++++++++++ src/odf/grammar.py | 7 +++++++ src/odf/odf2xhtml.py | 19 +++++++++++++++---- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/odf/element.py b/src/odf/element.py index 9754c251b0..f0938ba53e 100644 --- a/src/odf/element.py +++ b/src/odf/element.py @@ -165,6 +165,18 @@ class Node(xml.dom.Node): oldChild.parentNode = None return oldChild + def __str__(self): + val = [] + for c in self.childNodes: + val.append(str(c)) + return ''.join(val) + + def __unicode__(self): + val = [] + for c in self.childNodes: + val.append(unicode(c)) + return u''.join(val) + defproperty(Node, "firstChild", doc="First child node, or None.") defproperty(Node, "lastChild", doc="Last child node, or None.") @@ -221,6 +233,9 @@ class Text(Childless, Node): self.data = data def __str__(self): + return self.data.encode() + + def __unicode__(self): return self.data def toXml(self,level,f): @@ -452,3 +467,9 @@ class Element(Node): obj = element(check_grammar=False) return self._getElementsByObj(obj,[]) + def isInstanceOf(self, element): + """ This is a check to see if the object is an instance of a type """ + obj = element(check_grammar=False) + return self.qname == obj.qname + + diff --git a/src/odf/grammar.py b/src/odf/grammar.py index f71d72cca3..09ec02cbaa 100644 --- a/src/odf/grammar.py +++ b/src/odf/grammar.py @@ -4670,6 +4670,7 @@ allowed_attributes = { (NUMBERNS,u'boolean-style'):( (NUMBERNS,u'transliteration-language'), (STYLENS,u'name'), + (STYLENS,u'display-name'), (NUMBERNS,u'language'), (NUMBERNS,u'title'), (NUMBERNS,u'country'), @@ -4681,6 +4682,7 @@ allowed_attributes = { (NUMBERNS,u'currency-style'):( (NUMBERNS,u'transliteration-language'), (STYLENS,u'name'), + (STYLENS,u'display-name'), (NUMBERNS,u'language'), (NUMBERNS,u'title'), (NUMBERNS,u'country'), @@ -4698,6 +4700,7 @@ allowed_attributes = { (NUMBERNS,u'date-style'):( (NUMBERNS,u'transliteration-language'), (STYLENS,u'name'), + (STYLENS,u'display-name'), (NUMBERNS,u'language'), (NUMBERNS,u'title'), (NUMBERNS,u'country'), @@ -4753,6 +4756,7 @@ allowed_attributes = { (NUMBERNS,u'number-style'):( (NUMBERNS,u'transliteration-language'), (STYLENS,u'name'), + (STYLENS,u'display-name'), (NUMBERNS,u'language'), (NUMBERNS,u'title'), (NUMBERNS,u'country'), @@ -4765,6 +4769,7 @@ allowed_attributes = { (NUMBERNS,u'percentage-style'):( (NUMBERNS,u'transliteration-language'), (STYLENS,u'name'), + (STYLENS,u'display-name'), (NUMBERNS,u'language'), (NUMBERNS,u'title'), (NUMBERNS,u'country'), @@ -4794,6 +4799,7 @@ allowed_attributes = { (NUMBERNS,u'text-style'):( (NUMBERNS,u'transliteration-language'), (STYLENS,u'name'), + (STYLENS,u'display-name'), (NUMBERNS,u'language'), (NUMBERNS,u'title'), (NUMBERNS,u'country'), @@ -4806,6 +4812,7 @@ allowed_attributes = { (NUMBERNS,u'transliteration-language'), (NUMBERNS,u'transliteration-format'), (STYLENS,u'name'), + (STYLENS,u'display-name'), (NUMBERNS,u'language'), (NUMBERNS,u'title'), (NUMBERNS,u'country'), diff --git a/src/odf/odf2xhtml.py b/src/odf/odf2xhtml.py index b5df80f5d6..912e79cf3c 100644 --- a/src/odf/odf2xhtml.py +++ b/src/odf/odf2xhtml.py @@ -1,17 +1,17 @@ #!/usr/bin/python # -*- coding: utf-8 -*- # Copyright (C) 2006-2007 Søren Roug, European Environment Agency -# +# # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. -# +# # This library 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 # Lesser General Public License for more details. -# +# # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA @@ -47,7 +47,7 @@ from namespaces import ANIMNS, CHARTNS, CONFIGNS, DCNS, DR3DNS, DRAWNS, FONS, \ # # The real styles are declared in the element. They have a # family referring to the default-styles, and may have a parent style. -# +# # Styles have scope. The same name can be used for both paragraph and # character etc. styles Since CSS2 has no scope we use a prefix. (Not elegant) # In ODF a style can have a parent, these parents can be chained. @@ -376,6 +376,8 @@ class ODF2XHTML(handler.ContentHandler): (OFFICENS, "text"):(self.s_office_text, self.e_office_text), (OFFICENS, "scripts"):(self.s_ignorexml, None), (PRESENTATIONNS, "notes"):(self.s_ignorexml, None), +# (STYLENS, "default-page-layout"):(self.s_style_default_page_layout, self.e_style_page_layout), + (STYLENS, "default-page-layout"):(self.s_ignorexml, None), (STYLENS, "default-style"):(self.s_style_default_style, self.e_style_default_style), (STYLENS, "drawing-page-properties"):(self.s_style_handle_properties, None), (STYLENS, "font-face"):(self.s_style_font_face, None), @@ -834,8 +836,17 @@ class ODF2XHTML(handler.ContentHandler): self.stylestack.append(self.currentstyle) self.styledict[self.currentstyle] = {} + def s_style_default_page_layout(self, tag, attrs): + """ Collect the formatting for the default page layout style. + """ + self.currentstyle = "@page" + self.stylestack.append(self.currentstyle) + self.styledict[self.currentstyle] = {} + def s_style_page_layout(self, tag, attrs): """ Collect the formatting for the page layout style. + This won't work in CSS 2.1, as page identifiers are not allowed. + It is legal in CSS3, but the rest of the application doesn't specify when to use what page layout """ name = attrs[(STYLENS,'name')] name = name.replace(".","_")