More timezone aware fixes

This commit is contained in:
Kovid Goyal 2010-02-15 12:15:01 -07:00
parent 137d83c0e2
commit c82f3e4138
11 changed files with 76 additions and 63 deletions

View File

@ -7,12 +7,11 @@ __docformat__ = 'restructuredtext en'
Fetch metadata using Amazon AWS Fetch metadata using Amazon AWS
''' '''
import sys, re import sys, re
from datetime import datetime
from lxml import etree from lxml import etree
from calibre import browser from calibre import browser
from calibre.utils.date import parse_date from calibre.utils.date import parse_date, utcnow
from calibre.ebooks.metadata import MetaInformation, string_to_authors from calibre.ebooks.metadata import MetaInformation, string_to_authors
AWS_NS = 'http://webservices.amazon.com/AWSECommerceService/2005-10-05' AWS_NS = 'http://webservices.amazon.com/AWSECommerceService/2005-10-05'
@ -44,7 +43,7 @@ def get_social_metadata(title, authors, publisher, isbn):
try: try:
d = root.findtext('.//'+AWS('PublicationDate')) d = root.findtext('.//'+AWS('PublicationDate'))
if d: if d:
default = datetime.utcnow().replace(day=15) default = utcnow().replace(day=15)
d = parse_date(d[0].text, assume_utc=True, default=default) d = parse_date(d[0].text, assume_utc=True, default=default)
mi.pubdate = d mi.pubdate = d
except: except:

View File

@ -6,14 +6,13 @@ __docformat__ = 'restructuredtext en'
import sys, textwrap import sys, textwrap
from urllib import urlencode from urllib import urlencode
from functools import partial from functools import partial
from datetime import datetime
from lxml import etree from lxml import etree
from calibre import browser, preferred_encoding from calibre import browser, preferred_encoding
from calibre.ebooks.metadata import MetaInformation from calibre.ebooks.metadata import MetaInformation
from calibre.utils.config import OptionParser from calibre.utils.config import OptionParser
from calibre.utils.date import parse_date from calibre.utils.date import parse_date, utcnow
NAMESPACES = { NAMESPACES = {
'openSearch':'http://a9.com/-/spec/opensearchrss/1.0/', 'openSearch':'http://a9.com/-/spec/opensearchrss/1.0/',
@ -156,7 +155,7 @@ class ResultList(list):
try: try:
d = date(entry) d = date(entry)
if d: if d:
default = datetime.utcnow().replace(day=15) default = utcnow().replace(day=15)
d = parse_date(d[0].text, assume_utc=True, default=default) d = parse_date(d[0].text, assume_utc=True, default=default)
else: else:
d = None d = None

View File

@ -11,11 +11,11 @@ __docformat__ = 'restructuredtext en'
from struct import pack, unpack from struct import pack, unpack
from cStringIO import StringIO from cStringIO import StringIO
from datetime import datetime
from calibre.ebooks.mobi import MobiError from calibre.ebooks.mobi import MobiError
from calibre.ebooks.mobi.writer import rescale_image, MAX_THUMB_DIMEN from calibre.ebooks.mobi.writer import rescale_image, MAX_THUMB_DIMEN
from calibre.ebooks.mobi.langcodes import iana2mobi from calibre.ebooks.mobi.langcodes import iana2mobi
from calibre.utils.date import now as nowf
class StreamSlicer(object): class StreamSlicer(object):
@ -331,7 +331,7 @@ class MetadataUpdater(object):
recs.append((106, self.timestamp)) recs.append((106, self.timestamp))
pop_exth_record(106) pop_exth_record(106)
else: else:
recs.append((106, str(datetime.now()).encode(self.codec, 'replace'))) recs.append((106, nowf().isoformat().encode(self.codec, 'replace')))
pop_exth_record(106) pop_exth_record(106)
if self.cover_record is not None: if self.cover_record is not None:
recs.append((201, pack('>I', self.cover_rindex))) recs.append((201, pack('>I', self.cover_rindex)))

View File

@ -4,13 +4,11 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
Read data from .mobi files Read data from .mobi files
''' '''
import datetime
import functools import functools
import os import os
import re import re
import struct import struct
import textwrap import textwrap
import cStringIO import cStringIO
try: try:
@ -23,6 +21,7 @@ from lxml import html, etree
from calibre import entity_to_unicode, CurrentDir from calibre import entity_to_unicode, CurrentDir
from calibre.utils.filenames import ascii_filename from calibre.utils.filenames import ascii_filename
from calibre.utils.date import parse_date
from calibre.ptempfile import TemporaryDirectory from calibre.ptempfile import TemporaryDirectory
from calibre.ebooks import DRMError from calibre.ebooks import DRMError
from calibre.ebooks.chardet import ENCODING_PATS from calibre.ebooks.chardet import ENCODING_PATS
@ -96,8 +95,7 @@ class EXTHHeader(object):
self.mi.tags = list(set(self.mi.tags)) self.mi.tags = list(set(self.mi.tags))
elif id == 106: elif id == 106:
try: try:
self.mi.publish_date = datetime.datetime.strptime( self.mi.pubdate = parse_date(content, as_utc=False)
content, '%Y-%m-%d', ).date()
except: except:
pass pass
elif id == 108: elif id == 108:

View File

@ -10,7 +10,6 @@ import os
import re import re
import time import time
import traceback import traceback
from datetime import datetime, timedelta
from PyQt4.Qt import SIGNAL, QObject, QCoreApplication, Qt, QTimer, QThread, QDate, \ from PyQt4.Qt import SIGNAL, QObject, QCoreApplication, Qt, QTimer, QThread, QDate, \
QPixmap, QListWidgetItem, QDialog QPixmap, QListWidgetItem, QDialog
@ -29,6 +28,7 @@ from calibre.ebooks.metadata.library_thing import cover_from_isbn
from calibre import islinux from calibre import islinux
from calibre.ebooks.metadata.meta import get_metadata from calibre.ebooks.metadata.meta import get_metadata
from calibre.utils.config import prefs, tweaks from calibre.utils.config import prefs, tweaks
from calibre.utils.date import qt_to_dt
from calibre.customize.ui import run_plugins_on_import, get_isbndb_key from calibre.customize.ui import run_plugins_on_import, get_isbndb_key
from calibre.gui2.dialogs.config.social import SocialMetadata from calibre.gui2.dialogs.config.social import SocialMetadata
@ -354,12 +354,9 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
self.comments.setPlainText(comments if comments else '') self.comments.setPlainText(comments if comments else '')
cover = self.db.cover(row) cover = self.db.cover(row)
pubdate = db.pubdate(self.id, index_is_id=True) pubdate = db.pubdate(self.id, index_is_id=True)
self.local_timezone_offset = timedelta(seconds=time.timezone) - timedelta(hours=time.daylight)
pubdate = pubdate - self.local_timezone_offset
self.pubdate.setDate(QDate(pubdate.year, pubdate.month, self.pubdate.setDate(QDate(pubdate.year, pubdate.month,
pubdate.day)) pubdate.day))
timestamp = db.timestamp(self.id, index_is_id=True) timestamp = db.timestamp(self.id, index_is_id=True)
timestamp = timestamp - self.local_timezone_offset
self.date.setDate(QDate(timestamp.year, timestamp.month, self.date.setDate(QDate(timestamp.year, timestamp.month,
timestamp.day)) timestamp.day))
@ -583,7 +580,6 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
if book.isbn: self.isbn.setText(book.isbn) if book.isbn: self.isbn.setText(book.isbn)
if book.pubdate: if book.pubdate:
d = book.pubdate d = book.pubdate
d = d - self.local_timezone_offset
self.pubdate.setDate(QDate(d.year, d.month, d.day)) self.pubdate.setDate(QDate(d.year, d.month, d.day))
summ = book.comments summ = book.comments
if summ: if summ:
@ -656,12 +652,10 @@ class MetadataSingleDialog(ResizableDialog, Ui_MetadataSingleDialog):
self.db.set_series_index(self.id, self.series_index.value(), notify=False) self.db.set_series_index(self.id, self.series_index.value(), notify=False)
self.db.set_comment(self.id, qstring_to_unicode(self.comments.toPlainText()), notify=False) self.db.set_comment(self.id, qstring_to_unicode(self.comments.toPlainText()), notify=False)
d = self.pubdate.date() d = self.pubdate.date()
d = datetime(d.year(), d.month(), d.day()) d = qt_to_dt(d)
d = d + self.local_timezone_offset
self.db.set_pubdate(self.id, d) self.db.set_pubdate(self.id, d)
d = self.date.date() d = self.date.date()
d = datetime(d.year(), d.month(), d.day()) d = qt_to_dt(d)
d = d + self.local_timezone_offset
self.db.set_timestamp(self.id, d) self.db.set_timestamp(self.id, d)
if self.cover_changed: if self.cover_changed:

View File

@ -1,8 +1,7 @@
from calibre.ebooks.metadata import authors_to_string from calibre.ebooks.metadata import authors_to_string
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import os, textwrap, traceback, time, re import os, textwrap, traceback, re
from datetime import timedelta, datetime
from operator import attrgetter from operator import attrgetter
from math import cos, sin, pi from math import cos, sin, pi
@ -25,6 +24,7 @@ from calibre.utils.search_query_parser import SearchQueryParser
from calibre.ebooks.metadata.meta import set_metadata as _set_metadata from calibre.ebooks.metadata.meta import set_metadata as _set_metadata
from calibre.ebooks.metadata import string_to_authors, fmt_sidx from calibre.ebooks.metadata import string_to_authors, fmt_sidx
from calibre.utils.config import tweaks from calibre.utils.config import tweaks
from calibre.utils.date import dt_factory, qt_to_dt, isoformat
class LibraryDelegate(QItemDelegate): class LibraryDelegate(QItemDelegate):
COLOR = QColor("blue") COLOR = QColor("blue")
@ -567,13 +567,11 @@ class BooksModel(QAbstractTableModel):
def timestamp(r): def timestamp(r):
dt = self.db.data[r][tmdx] dt = self.db.data[r][tmdx]
if dt: if dt:
dt = dt - timedelta(seconds=time.timezone) + timedelta(hours=time.daylight)
return QDate(dt.year, dt.month, dt.day) return QDate(dt.year, dt.month, dt.day)
def pubdate(r): def pubdate(r):
dt = self.db.data[r][pddx] dt = self.db.data[r][pddx]
if dt: if dt:
dt = dt - timedelta(seconds=time.timezone) + timedelta(hours=time.daylight)
return QDate(dt.year, dt.month, dt.day) return QDate(dt.year, dt.month, dt.day)
def rating(r): def rating(r):
@ -670,13 +668,11 @@ class BooksModel(QAbstractTableModel):
elif column == 'timestamp': elif column == 'timestamp':
if val.isNull() or not val.isValid(): if val.isNull() or not val.isValid():
return False return False
dt = datetime(val.year(), val.month(), val.day()) + timedelta(seconds=time.timezone) - timedelta(hours=time.daylight) self.db.set_timestamp(id, qt_to_dt(val, as_utc=False))
self.db.set_timestamp(id, dt)
elif column == 'pubdate': elif column == 'pubdate':
if val.isNull() or not val.isValid(): if val.isNull() or not val.isValid():
return False return False
dt = datetime(val.year(), val.month(), val.day()) + timedelta(seconds=time.timezone) - timedelta(hours=time.daylight) self.db.set_pubdate(id, qt_to_dt(val, as_utc=False))
self.db.set_pubdate(id, dt)
else: else:
self.db.set(row, column, val) self.db.set(row, column, val)
self.emit(SIGNAL("dataChanged(QModelIndex, QModelIndex)"), \ self.emit(SIGNAL("dataChanged(QModelIndex, QModelIndex)"), \
@ -1032,7 +1028,8 @@ class DeviceBooksModel(BooksModel):
def datecmp(x, y): def datecmp(x, y):
x = self.db[x].datetime x = self.db[x].datetime
y = self.db[y].datetime y = self.db[y].datetime
return cmp(datetime(*x[0:6]), datetime(*y[0:6])) return cmp(dt_factory(x, assume_utc=True), dt_factory(y,
assume_utc=True))
def sizecmp(x, y): def sizecmp(x, y):
x, y = int(self.db[x].size), int(self.db[y].size) x, y = int(self.db[x].size), int(self.db[y].size)
return cmp(x, y) return cmp(x, y)
@ -1081,10 +1078,8 @@ class DeviceBooksModel(BooksModel):
type = ext[1:].lower() type = ext[1:].lower()
data[_('Format')] = type data[_('Format')] = type
data[_('Path')] = item.path data[_('Path')] = item.path
dt = item.datetime dt = dt_factory(item.datetime, assume_utc=True)
dt = datetime(*dt[0:6]) data[_('Timestamp')] = isoformat(dt, sep=' ', as_utc=False)
dt = dt - timedelta(seconds=time.timezone) + timedelta(hours=time.daylight)
data[_('Timestamp')] = strftime('%a %b %d %H:%M:%S %Y', dt.timetuple())
data[_('Tags')] = ', '.join(item.tags) data[_('Tags')] = ', '.join(item.tags)
self.emit(SIGNAL('new_bookdisplay_data(PyQt_PyObject)'), data) self.emit(SIGNAL('new_bookdisplay_data(PyQt_PyObject)'), data)
@ -1119,8 +1114,7 @@ class DeviceBooksModel(BooksModel):
return QVariant(BooksView.human_readable(size)) return QVariant(BooksView.human_readable(size))
elif col == 3: elif col == 3:
dt = self.db[self.map[row]].datetime dt = self.db[self.map[row]].datetime
dt = datetime(*dt[0:6]) dt = dt_factory(dt, assume_utc=True, as_utc=False)
dt = dt - timedelta(seconds=time.timezone) + timedelta(hours=time.daylight)
return QVariant(strftime(BooksView.TIME_FMT, dt.timetuple())) return QVariant(strftime(BooksView.TIME_FMT, dt.timetuple()))
elif col == 4: elif col == 4:
tags = self.db[self.map[row]].tags tags = self.db[self.map[row]].tags

View File

@ -11,7 +11,6 @@ import sys, textwrap, operator, os, re, logging, cStringIO
import __builtin__ import __builtin__
from itertools import repeat from itertools import repeat
from logging.handlers import RotatingFileHandler from logging.handlers import RotatingFileHandler
from datetime import datetime
from threading import Thread from threading import Thread
import cherrypy import cherrypy
@ -31,15 +30,16 @@ from calibre.utils.config import config_dir
from calibre.utils.mdns import publish as publish_zeroconf, \ from calibre.utils.mdns import publish as publish_zeroconf, \
stop_server as stop_zeroconf stop_server as stop_zeroconf
from calibre.ebooks.metadata import fmt_sidx, title_sort from calibre.ebooks.metadata import fmt_sidx, title_sort
from calibre.utils.date import now as nowf, fromtimestamp
def strftime(fmt='%Y/%m/%d %H:%M:%S', dt=None): def strftime(fmt='%Y/%m/%d %H:%M:%S', dt=None):
if not hasattr(dt, 'timetuple'): if not hasattr(dt, 'timetuple'):
dt = datetime.now() dt = nowf()
dt = dt.timetuple() dt = dt.timetuple()
try: try:
return _strftime(fmt, dt) return _strftime(fmt, dt)
except: except:
return _strftime(fmt, datetime.now().timetuple()) return _strftime(fmt, nowf().timetuple())
def expose(func): def expose(func):
@ -351,7 +351,7 @@ class LibraryServer(object):
map(int, self.opts.max_cover.split('x')) map(int, self.opts.max_cover.split('x'))
self.max_stanza_items = opts.max_opds_items self.max_stanza_items = opts.max_opds_items
path = P('content_server') path = P('content_server')
self.build_time = datetime.fromtimestamp(os.stat(path).st_mtime) self.build_time = fromtimestamp(os.stat(path).st_mtime)
self.default_cover = open(P('content_server/default_cover.jpg'), 'rb').read() self.default_cover = open(P('content_server/default_cover.jpg'), 'rb').read()
cherrypy.config.update({ cherrypy.config.update({
@ -429,7 +429,7 @@ class LibraryServer(object):
cherrypy.response.headers['Content-Type'] = 'image/jpeg' cherrypy.response.headers['Content-Type'] = 'image/jpeg'
cherrypy.response.timeout = 3600 cherrypy.response.timeout = 3600
path = getattr(cover, 'name', False) path = getattr(cover, 'name', False)
updated = datetime.utcfromtimestamp(os.stat(path).st_mtime) if path and \ updated = fromtimestamp(os.stat(path).st_mtime) if path and \
os.access(path, os.R_OK) else self.build_time os.access(path, os.R_OK) else self.build_time
cherrypy.response.headers['Last-Modified'] = self.last_modified(updated) cherrypy.response.headers['Last-Modified'] = self.last_modified(updated)
try: try:
@ -476,7 +476,7 @@ class LibraryServer(object):
cherrypy.response.timeout = 3600 cherrypy.response.timeout = 3600
path = getattr(fmt, 'name', None) path = getattr(fmt, 'name', None)
if path and os.path.exists(path): if path and os.path.exists(path):
updated = datetime.utcfromtimestamp(os.stat(path).st_mtime) updated = fromtimestamp(os.stat(path).st_mtime)
cherrypy.response.headers['Last-Modified'] = self.last_modified(updated) cherrypy.response.headers['Last-Modified'] = self.last_modified(updated)
return fmt.read() return fmt.read()
@ -841,7 +841,7 @@ class LibraryServer(object):
if not os.path.exists(path): if not os.path.exists(path):
raise cherrypy.HTTPError(404, '%s not found'%name) raise cherrypy.HTTPError(404, '%s not found'%name)
if self.opts.develop: if self.opts.develop:
lm = datetime.fromtimestamp(os.stat(path).st_mtime) lm = fromtimestamp(os.stat(path).st_mtime)
cherrypy.response.headers['Last-Modified'] = self.last_modified(lm) cherrypy.response.headers['Last-Modified'] = self.last_modified(lm)
return open(path, 'rb').read() return open(path, 'rb').read()

View File

@ -11,8 +11,8 @@ from datetime import datetime
from dateutil.parser import parse from dateutil.parser import parse
from dateutil.tz import tzlocal, tzutc from dateutil.tz import tzlocal, tzutc
_utc_tz = tzutc() utc_tz = _utc_tz = tzutc()
_local_tz = tzlocal() local_tz = _local_tz = tzlocal()
def parse_date(date_string, assume_utc=False, as_utc=True, default=None): def parse_date(date_string, assume_utc=False, as_utc=True, default=None):
''' '''
@ -34,17 +34,48 @@ def parse_date(date_string, assume_utc=False, as_utc=True, default=None):
dt = parse(date_string, default=default) dt = parse(date_string, default=default)
if dt.tzinfo is None: if dt.tzinfo is None:
dt = dt.replace(tzinfo=_utc_tz if assume_utc else _local_tz) dt = dt.replace(tzinfo=_utc_tz if assume_utc else _local_tz)
dt = dt.astimezone(_utc_tz if as_utc else _local_tz) return dt.astimezone(_utc_tz if as_utc else _local_tz)
def strptime(val, fmt, assume_utc=False, as_utc=True):
dt = datetime.strptime(val, fmt)
if dt.tzinfo is None:
dt = dt.replace(tzinfo=_utc_tz if assume_utc else _local_tz)
return dt.astimezone(_utc_tz if as_utc else _local_tz)
def dt_factory(time_t, assume_utc=False, as_utc=True):
dt = datetime(time_t[0:6])
if dt.tzinfo is None:
dt = dt.replace(tzinfo=_utc_tz if assume_utc else _local_tz)
return dt.astimezone(_utc_tz if as_utc else _local_tz)
def qt_to_dt(qdate_or_qdatetime, as_utc=True):
from PyQt4.Qt import Qt
o = qdate_or_qdatetime
if hasattr(o, 'toUTC'):
# QDateTime
o = unicode(o.toUTC().toString(Qt.ISODate))
return parse_date(o, assume_utc=True, as_utc=as_utc)
dt = datetime(o.year(), o.month(), o.day()).replace(tzinfo=_local_tz)
return dt.astimezone(_utc_tz if as_utc else _local_tz)
def fromtimestamp(ctime, as_utc=True):
dt = datetime.utcfromtimestamp().replace(tzinfo=_utc_tz)
if not as_utc:
dt = dt.astimezone(_local_tz)
return dt return dt
def isoformat(date_time, assume_utc=False, as_utc=True): def fromordinal(day, as_utc=True):
return datetime.fromordinal(day).replace(
tzinfo=_utc_tz if as_utc else _local_tz)
def isoformat(date_time, assume_utc=False, as_utc=True, sep='T'):
if not hasattr(date_time, 'tzinfo'): if not hasattr(date_time, 'tzinfo'):
return unicode(date_time.isoformat()) return unicode(date_time.isoformat())
if date_time.tzinfo is None: if date_time.tzinfo is None:
date_time = date_time.replace(tzinfo=_utc_tz if assume_utc else date_time = date_time.replace(tzinfo=_utc_tz if assume_utc else
_local_tz) _local_tz)
date_time = date_time.astimezone(_utc_tz if as_utc else _local_tz) date_time = date_time.astimezone(_utc_tz if as_utc else _local_tz)
return unicode(date_time.isoformat()) return unicode(date_time.isoformat(sep))
def now(): def now():
return datetime.now().replace(tzinfo=_local_tz) return datetime.now().replace(tzinfo=_local_tz)

View File

@ -6,17 +6,16 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
Contains the logic for parsing feeds. Contains the logic for parsing feeds.
''' '''
import time, traceback, copy, re import time, traceback, copy, re
from datetime import datetime
from lxml import html
from calibre.web.feeds.feedparser import parse from calibre.web.feeds.feedparser import parse
from calibre.utils.logging import default_log from calibre.utils.logging import default_log
from calibre import entity_to_unicode from calibre import entity_to_unicode
from lxml import html from calibre.utils.date import dt_factory, utcnow, local_tz
class Article(object): class Article(object):
time_offset = datetime.now() - datetime.utcnow()
def __init__(self, id, title, url, author, summary, published, content): def __init__(self, id, title, url, author, summary, published, content):
self.downloaded = False self.downloaded = False
self.id = id self.id = id
@ -48,8 +47,8 @@ class Article(object):
self.author = author self.author = author
self.content = content self.content = content
self.date = published self.date = published
self.utctime = datetime(*self.date[:6]) self.utctime = dt_factory(self.date, assume_utc=True, as_utc=True)
self.localtime = self.utctime + self.time_offset self.localtime = self.utctime.astimezone(local_tz)
@dynamic_property @dynamic_property
def title(self): def title(self):
@ -146,7 +145,7 @@ class Feed(object):
content = item.get('content', '') content = item.get('content', '')
author = item.get('author', '') author = item.get('author', '')
article = Article(id, title, link, author, description, published, content) article = Article(id, title, link, author, description, published, content)
delta = datetime.utcnow() - article.utctime delta = utcnow() - article.utctime
if delta.days*24*3600 + delta.seconds <= 24*3600*self.oldest_article: if delta.days*24*3600 + delta.seconds <= 24*3600*self.oldest_article:
self.articles.append(article) self.articles.append(article)
else: else:
@ -183,7 +182,7 @@ class Feed(object):
if not link and not content: if not link and not content:
return return
article = Article(id, title, link, author, description, published, content) article = Article(id, title, link, author, description, published, content)
delta = datetime.utcnow() - article.utctime delta = utcnow() - article.utctime
if delta.days*24*3600 + delta.seconds <= 24*3600*self.oldest_article: if delta.days*24*3600 + delta.seconds <= 24*3600*self.oldest_article:
self.articles.append(article) self.articles.append(article)
else: else:

View File

@ -11,7 +11,6 @@ import os, time, traceback, re, urlparse, sys
from collections import defaultdict from collections import defaultdict
from functools import partial from functools import partial
from contextlib import nested, closing from contextlib import nested, closing
from datetime import datetime
from calibre import browser, __appname__, iswindows, \ from calibre import browser, __appname__, iswindows, \
@ -29,7 +28,7 @@ from calibre.web.fetch.simple import RecursiveFetcher
from calibre.utils.threadpool import WorkRequest, ThreadPool, NoResultsPending from calibre.utils.threadpool import WorkRequest, ThreadPool, NoResultsPending
from calibre.ptempfile import PersistentTemporaryFile, \ from calibre.ptempfile import PersistentTemporaryFile, \
PersistentTemporaryDirectory PersistentTemporaryDirectory
from calibre.utils.date import now as nowf
class BasicNewsRecipe(Recipe): class BasicNewsRecipe(Recipe):
''' '''
@ -1080,11 +1079,11 @@ class BasicNewsRecipe(Recipe):
mi.publisher = __appname__ mi.publisher = __appname__
mi.author_sort = __appname__ mi.author_sort = __appname__
mi.publication_type = 'periodical:'+self.publication_type mi.publication_type = 'periodical:'+self.publication_type
mi.timestamp = datetime.now() mi.timestamp = nowf()
mi.comments = self.description mi.comments = self.description
if not isinstance(mi.comments, unicode): if not isinstance(mi.comments, unicode):
mi.comments = mi.comments.decode('utf-8', 'replace') mi.comments = mi.comments.decode('utf-8', 'replace')
mi.pubdate = datetime.now() mi.pubdate = nowf()
opf_path = os.path.join(dir, 'index.opf') opf_path = os.path.join(dir, 'index.opf')
ncx_path = os.path.join(dir, 'index.ncx') ncx_path = os.path.join(dir, 'index.ncx')

View File

@ -8,14 +8,14 @@ __docformat__ = 'restructuredtext en'
import os, calendar import os, calendar
from threading import RLock from threading import RLock
from datetime import datetime, timedelta from datetime import timedelta
from lxml import etree from lxml import etree
from lxml.builder import ElementMaker from lxml.builder import ElementMaker
from calibre import browser from calibre import browser
from calibre.utils.date import parse_date, now as nowf, utcnow, tzlocal, \ from calibre.utils.date import parse_date, now as nowf, utcnow, tzlocal, \
isoformat isoformat, fromordinal
NS = 'http://calibre-ebook.com/recipe_collection' NS = 'http://calibre-ebook.com/recipe_collection'
E = ElementMaker(namespace=NS, nsmap={None:NS}) E = ElementMaker(namespace=NS, nsmap={None:NS})
@ -163,7 +163,7 @@ class SchedulerConfig(object):
self.root.remove(x) self.root.remove(x)
break break
if last_downloaded is None: if last_downloaded is None:
last_downloaded = datetime.fromordinal(1) last_downloaded = fromordinal(1)
sr = E.scheduled_recipe({ sr = E.scheduled_recipe({
'id' : recipe.get('id'), 'id' : recipe.get('id'),
'title': recipe.get('title'), 'title': recipe.get('title'),