mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix display of dates on non english windows
This commit is contained in:
parent
5c399a268e
commit
5e494d0f80
@ -22,6 +22,9 @@ LIBZ = '/lib/libz.so.1'
|
||||
LIBBZ2 = '/lib/libbz2.so.1'
|
||||
LIBUSB = '/usr/lib/libusb.so'
|
||||
LIBPOPPLER = '/usr/lib/libpoppler.so.3'
|
||||
LIBXML2 = '/usr/lib/libxml2.so.2'
|
||||
LIBXSLT = '/usr/lib/libxslt.so.1'
|
||||
LIBEXSLT = '/usr/lib/libexslt.so.0'
|
||||
|
||||
|
||||
CALIBRESRC = os.path.join(CALIBREPREFIX, 'src')
|
||||
@ -121,7 +124,7 @@ binaries += [('pdftohtml', PDFTOHTML, 'BINARY'),
|
||||
|
||||
print 'Adding external libraries...'
|
||||
binaries += [ (os.path.basename(x), x, 'BINARY') for x in (SQLITE, DBUS,
|
||||
LIBMNG, LIBZ, LIBBZ2, LIBUSB, LIBPOPPLER)]
|
||||
LIBMNG, LIBZ, LIBBZ2, LIBUSB, LIBPOPPLER, LIBXML2, LIBXSLT, LIBEXSLT)]
|
||||
|
||||
|
||||
qt = []
|
||||
|
@ -320,11 +320,10 @@ class LoggingInterface:
|
||||
|
||||
|
||||
def strftime(fmt, t=time.localtime()):
|
||||
'''
|
||||
A version of strtime that returns unicode strings.
|
||||
'''
|
||||
result = time.strftime(fmt, t)
|
||||
return unicode(result, preferred_encoding, 'replace')
|
||||
''' A version of strtime that returns unicode strings. '''
|
||||
if iswindows:
|
||||
return plugins['winutil'].strftime(unicode(fmt, preferred_encoding), t)
|
||||
return time.strftime(fmt, t).decode(preferred_encoding, 'replace')
|
||||
|
||||
def entity_to_unicode(match, exceptions=[], encoding='cp1252'):
|
||||
'''
|
||||
|
@ -2,7 +2,7 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
__appname__ = 'calibre'
|
||||
__version__ = '0.4.84b1'
|
||||
__version__ = '0.4.84b2'
|
||||
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
|
||||
'''
|
||||
Various run time constants.
|
||||
|
@ -9,11 +9,9 @@ from calibre.ebooks.lrf.html.convert_from import process_file
|
||||
from calibre.web.feeds.main import option_parser as feeds_option_parser
|
||||
from calibre.web.feeds.main import run_recipe
|
||||
from calibre.ptempfile import PersistentTemporaryDirectory
|
||||
from calibre import sanitize_file_name
|
||||
from calibre import sanitize_file_name, strftime
|
||||
|
||||
import sys, os, time
|
||||
|
||||
import parser
|
||||
import sys, os
|
||||
|
||||
def option_parser():
|
||||
parser = feeds_option_parser()
|
||||
@ -51,7 +49,7 @@ def main(args=sys.argv, notification=None, handler=None):
|
||||
|
||||
if not opts.output:
|
||||
ext = '.lrs' if opts.lrs else '.lrf'
|
||||
fname = recipe.title + time.strftime(recipe.timefmt)+ext
|
||||
fname = recipe.title + strftime(recipe.timefmt)+ext
|
||||
opts.output = os.path.join(os.getcwd(), sanitize_file_name(fname))
|
||||
print 'Generating LRF...'
|
||||
process_file(htmlfile, opts)
|
||||
|
@ -2,10 +2,10 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
'''Convert websites into LRF files.'''
|
||||
|
||||
import sys, time, tempfile, shutil, os, logging, imp, inspect, re
|
||||
import sys, tempfile, shutil, os, logging, imp, inspect, re
|
||||
from urlparse import urlsplit
|
||||
|
||||
from calibre import __appname__, setup_cli_handlers, CommandLineError
|
||||
from calibre import __appname__, setup_cli_handlers, CommandLineError, strftime
|
||||
from calibre.ebooks.lrf import option_parser as lrf_option_parser
|
||||
from calibre.ebooks.lrf.html.convert_from import process_file
|
||||
|
||||
@ -128,7 +128,7 @@ def process_profile(args, options, logger=None):
|
||||
title = profile.title
|
||||
if not title:
|
||||
title = urlsplit(options.url).netloc
|
||||
options.title = title + time.strftime(profile.timefmt, time.localtime())
|
||||
options.title = title + strftime(profile.timefmt)
|
||||
|
||||
options.match_regexps += profile.match_regexps
|
||||
options.preprocess_regexps = profile.preprocess_regexps
|
||||
|
@ -306,7 +306,7 @@ class FileDialog(QObject):
|
||||
QObject.connect(self.fd, SIGNAL('accepted()'), self.save_dir)
|
||||
self.accepted = self.fd.exec_() == QFileDialog.Accepted
|
||||
else:
|
||||
dir = dynamic.get(self.dialog_name, default=os.path.expanduser('~'))
|
||||
dir = dynamic.get(self.dialog_name, os.path.expanduser('~'))
|
||||
self.selected_files = []
|
||||
if mode == QFileDialog.AnyFile:
|
||||
f = qstring_to_unicode(
|
||||
|
@ -13,7 +13,7 @@ from PyQt4.QtGui import QTableView, QProgressDialog, QAbstractItemView, QColor,
|
||||
from PyQt4.QtCore import QAbstractTableModel, QVariant, Qt, QString, \
|
||||
QCoreApplication, SIGNAL, QObject, QSize, QModelIndex
|
||||
|
||||
from calibre import preferred_encoding
|
||||
from calibre import strftime
|
||||
from calibre.ptempfile import PersistentTemporaryFile
|
||||
from calibre.library.database import LibraryDatabase, text_to_tokens
|
||||
from calibre.gui2 import NONE, TableView, qstring_to_unicode, config
|
||||
@ -370,7 +370,7 @@ class BooksModel(QAbstractTableModel):
|
||||
dt = self.db.timestamp(row)
|
||||
if dt:
|
||||
dt = dt - timedelta(seconds=time.timezone) + timedelta(hours=time.daylight)
|
||||
return QVariant(dt.strftime(BooksView.TIME_FMT).decode(preferred_encoding, 'replace'))
|
||||
return QVariant(strftime(BooksView.TIME_FMT, dt.timetuple()))
|
||||
elif col == 4:
|
||||
r = self.db.rating(row)
|
||||
r = r/2 if r else 0
|
||||
@ -690,7 +690,7 @@ class DeviceBooksModel(BooksModel):
|
||||
dt = item.datetime
|
||||
dt = datetime(*dt[0:6])
|
||||
dt = dt - timedelta(seconds=time.timezone) + timedelta(hours=time.daylight)
|
||||
data[_('Timestamp')] = dt.strftime('%a %b %d %H:%M:%S %Y')
|
||||
data[_('Timestamp')] = strftime('%a %b %d %H:%M:%S %Y', dt.timetuple())
|
||||
data[_('Tags')] = ', '.join(item.tags)
|
||||
self.emit(SIGNAL('new_bookdisplay_data(PyQt_PyObject)'), data)
|
||||
|
||||
@ -731,7 +731,7 @@ class DeviceBooksModel(BooksModel):
|
||||
dt = self.db[self.map[row]].datetime
|
||||
dt = datetime(*dt[0:6])
|
||||
dt = dt - timedelta(seconds=time.timezone) + timedelta(hours=time.daylight)
|
||||
return QVariant(dt.strftime(BooksView.TIME_FMT))
|
||||
return QVariant(strftime(BooksView.TIME_FMT, dt.timetuple()))
|
||||
elif col == 4:
|
||||
tags = self.db[self.map[row]].tags
|
||||
if tags:
|
||||
|
@ -2,7 +2,8 @@
|
||||
# Invoke with nmake /f Makefile.winutil
|
||||
|
||||
test : winutil.pyd
|
||||
python.exe -c "import winutil; winutil.set_debug(True); print winutil.get_usb_devices(); print winutil.get_mounted_volumes_for_usb_device(0x054c, 0x031e)"
|
||||
python.exe -c "import winutil; winutil.set_debug(True); print repr(winutil.strftime(u'%b %a %A')); "
|
||||
#python.exe -c "import winutil; winutil.set_debug(True); print winutil.get_usb_devices(); print winutil.get_mounted_volumes_for_usb_device(0x054c, 0x031e)"
|
||||
|
||||
winutil.pyd : winutil.obj
|
||||
link.exe /DLL /nologo /INCREMENTAL:NO /LIBPATH:c:\Python25\libs \
|
||||
|
@ -57,12 +57,19 @@ wherever possible in this module.
|
||||
#define UNICODE
|
||||
#include <Windows.h>
|
||||
#include <Python.h>
|
||||
#include <structseq.h>
|
||||
#include <timefuncs.h>
|
||||
#include <shlobj.h>
|
||||
#include <stdio.h>
|
||||
#include <setupapi.h>
|
||||
#include <devguid.h>
|
||||
#include <cfgmgr32.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
|
||||
#define PyStructSequence_GET_ITEM(op, i) \
|
||||
(((PyStructSequence *)(op))->ob_item[i])
|
||||
|
||||
|
||||
#define BUFSIZE 512
|
||||
#define MAX_DRIVES 26
|
||||
@ -515,6 +522,143 @@ winutil_is_usb_device_connected(PyObject *self, PyObject *args) {
|
||||
return ans;
|
||||
}
|
||||
|
||||
static int
|
||||
gettmarg(PyObject *args, struct tm *p)
|
||||
{
|
||||
int y;
|
||||
memset((void *) p, '\0', sizeof(struct tm));
|
||||
|
||||
if (!PyArg_Parse(args, "(iiiiiiiii)",
|
||||
&y,
|
||||
&p->tm_mon,
|
||||
&p->tm_mday,
|
||||
&p->tm_hour,
|
||||
&p->tm_min,
|
||||
&p->tm_sec,
|
||||
&p->tm_wday,
|
||||
&p->tm_yday,
|
||||
&p->tm_isdst))
|
||||
return 0;
|
||||
if (y < 1900) {
|
||||
if (69 <= y && y <= 99)
|
||||
y += 1900;
|
||||
else if (0 <= y && y <= 68)
|
||||
y += 2000;
|
||||
else {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"year out of range");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
p->tm_year = y - 1900;
|
||||
p->tm_mon--;
|
||||
p->tm_wday = (p->tm_wday + 1) % 7;
|
||||
p->tm_yday--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
winutil_strftime(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *tup = NULL;
|
||||
struct tm buf;
|
||||
PyObject *format;
|
||||
const wchar_t *fmt;
|
||||
size_t fmtlen, buflen;
|
||||
wchar_t *outbuf = 0;
|
||||
size_t i;
|
||||
memset((void *) &buf, '\0', sizeof(buf));
|
||||
|
||||
if (!PyArg_ParseTuple(args, "U|O:strftime", &format, &tup))
|
||||
return NULL;
|
||||
|
||||
if (tup == NULL) {
|
||||
time_t tt = time(NULL);
|
||||
buf = *localtime(&tt);
|
||||
} else if (!gettmarg(tup, &buf))
|
||||
return NULL;
|
||||
|
||||
if (buf.tm_mon == -1)
|
||||
buf.tm_mon = 0;
|
||||
else if (buf.tm_mon < 0 || buf.tm_mon > 11) {
|
||||
PyErr_SetString(PyExc_ValueError, "month out of range");
|
||||
return NULL;
|
||||
}
|
||||
if (buf.tm_mday == 0)
|
||||
buf.tm_mday = 1;
|
||||
else if (buf.tm_mday < 0 || buf.tm_mday > 31) {
|
||||
PyErr_SetString(PyExc_ValueError, "day of month out of range");
|
||||
return NULL;
|
||||
}
|
||||
if (buf.tm_hour < 0 || buf.tm_hour > 23) {
|
||||
PyErr_SetString(PyExc_ValueError, "hour out of range");
|
||||
return NULL;
|
||||
}
|
||||
if (buf.tm_min < 0 || buf.tm_min > 59) {
|
||||
PyErr_SetString(PyExc_ValueError, "minute out of range");
|
||||
return NULL;
|
||||
}
|
||||
if (buf.tm_sec < 0 || buf.tm_sec > 61) {
|
||||
PyErr_SetString(PyExc_ValueError, "seconds out of range");
|
||||
return NULL;
|
||||
}
|
||||
/* tm_wday does not need checking of its upper-bound since taking
|
||||
``% 7`` in gettmarg() automatically restricts the range. */
|
||||
if (buf.tm_wday < 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "day of week out of range");
|
||||
return NULL;
|
||||
}
|
||||
if (buf.tm_yday == -1)
|
||||
buf.tm_yday = 0;
|
||||
else if (buf.tm_yday < 0 || buf.tm_yday > 365) {
|
||||
PyErr_SetString(PyExc_ValueError, "day of year out of range");
|
||||
return NULL;
|
||||
}
|
||||
if (buf.tm_isdst < -1 || buf.tm_isdst > 1) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"daylight savings flag out of range");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Convert the unicode string to a wchar one */
|
||||
fmtlen = PyUnicode_GET_SIZE(format);
|
||||
fmt = (wchar_t *)PyMem_Malloc((fmtlen+1)*sizeof(wchar_t));
|
||||
if (fmt == NULL) return PyErr_NoMemory();
|
||||
i = PyUnicode_AsWideChar((PyUnicodeObject *)format, fmt, fmtlen);
|
||||
if (i < fmtlen) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Failed to convert format string");
|
||||
PyMem_Free(fmt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 1024; ; i += i) {
|
||||
outbuf = (wchar_t *)PyMem_Malloc(i*sizeof(wchar_t));
|
||||
if (outbuf == NULL) {
|
||||
return PyErr_NoMemory();
|
||||
}
|
||||
buflen = wcsftime(outbuf, i, fmt, &buf);
|
||||
if (buflen > 0 || i >= 256 * fmtlen) {
|
||||
/* If the buffer is 256 times as long as the format,
|
||||
it's probably not failing for lack of room!
|
||||
More likely, the format yields an empty result,
|
||||
e.g. an empty format, or %Z when the timezone
|
||||
is unknown. */
|
||||
PyObject *ret;
|
||||
ret = PyUnicode_FromWideChar(outbuf, buflen);
|
||||
PyMem_Free(outbuf); PyMem_Free(fmt);
|
||||
return ret;
|
||||
}
|
||||
PyMem_Free(outbuf); PyMem_Free(fmt);
|
||||
#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
|
||||
/* VisualStudio .NET 2005 does this properly */
|
||||
if (buflen == 0 && errno == EINVAL) {
|
||||
PyErr_SetString(PyExc_ValueError, "Invalid format string");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static PyMethodDef WinutilMethods[] = {
|
||||
{"special_folder_path", winutil_folder_path, METH_VARARGS,
|
||||
@ -553,6 +697,15 @@ static PyMethodDef WinutilMethods[] = {
|
||||
"set_debug(bool)\n\nSet debugging mode."
|
||||
},
|
||||
|
||||
{"strftime", winutil_strftime, METH_VARARGS,
|
||||
"strftime(format[, tuple]) -> string\n\
|
||||
\n\
|
||||
Convert a time tuple to a string according to a format specification.\n\
|
||||
See the library reference manual for formatting codes. When the time tuple\n\
|
||||
is not present, current time as returned by localtime() is used. format must\n\
|
||||
be a unicode string. Returns unicode strings."
|
||||
},
|
||||
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
@ -4,6 +4,7 @@ __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import re, time
|
||||
from calibre import strftime
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
from calibre.ebooks.BeautifulSoup import NavigableString
|
||||
|
||||
@ -65,7 +66,7 @@ class NewYorker(BasicNewsRecipe):
|
||||
'title': title,
|
||||
'desc': desc, 'content':'',
|
||||
'url': href,
|
||||
'date': time.strftime('%a, %d %b', time.localtime()),
|
||||
'date': strftime('%a, %d %b'),
|
||||
}
|
||||
articles.append(art)
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
import re, string, time
|
||||
from calibre import strftime
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
from calibre.ebooks.BeautifulSoup import BeautifulSoup
|
||||
|
||||
@ -68,7 +69,7 @@ class Newsweek(BasicNewsRecipe):
|
||||
small = img['src']
|
||||
match = re.search(r'(\d+)_', small.rpartition('/')[-1])
|
||||
if match is not None:
|
||||
self.timefmt = time.strftime(' [%d %b, %Y]', time.strptime(match.group(1), '%y%m%d'))
|
||||
self.timefmt = strftime(' [%d %b, %Y]', time.strptime(match.group(1), '%y%m%d'))
|
||||
self.cover_url = small.replace('coversmall', 'coverlarge')
|
||||
|
||||
sections = self.get_sections(soup)
|
||||
@ -84,7 +85,7 @@ class Newsweek(BasicNewsRecipe):
|
||||
'title' : title,
|
||||
'url' : a['href'],
|
||||
'description':'', 'content':'',
|
||||
'date': time.strftime('%a, %d %b', time.localtime())
|
||||
'date': strftime('%a, %d %b')
|
||||
}
|
||||
if art['title'] and art['url']:
|
||||
sections[0][1].append(art)
|
||||
|
@ -5,7 +5,8 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
'''
|
||||
nytimes.com
|
||||
'''
|
||||
import time, string
|
||||
import string
|
||||
from calibre import strftime
|
||||
from calibre.web.feeds.recipes import BasicNewsRecipe
|
||||
|
||||
class NYTimes(BasicNewsRecipe):
|
||||
@ -59,7 +60,7 @@ class NYTimes(BasicNewsRecipe):
|
||||
url = self.print_version(a['href'])
|
||||
title = self.tag_to_string(a, use_alt=True).strip()
|
||||
description = ''
|
||||
pubdate = time.strftime('%a, %d %b', time.localtime())
|
||||
pubdate = strftime('%a, %d %b')
|
||||
summary = div.find(True, attrs={'class':'summary'})
|
||||
if summary:
|
||||
description = self.tag_to_string(summary, use_alt=False)
|
||||
|
@ -6,7 +6,7 @@ __docformat__ = 'restructuredtext en'
|
||||
'''
|
||||
smh.com.au
|
||||
'''
|
||||
import time
|
||||
from calibre import strftime
|
||||
from calibre.web.feeds.news import BasicNewsRecipe
|
||||
from calibre.ebooks.BeautifulSoup import BeautifulSoup
|
||||
|
||||
@ -44,7 +44,7 @@ class SMH(BasicNewsRecipe):
|
||||
articles.append({
|
||||
'title': title,
|
||||
'url' : url,
|
||||
'date' : time.strftime('%a, %d %b'),
|
||||
'date' : strftime('%a, %d %b'),
|
||||
'description' : '',
|
||||
'content' : '',
|
||||
})
|
||||
|
@ -2,9 +2,8 @@
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
import datetime
|
||||
from calibre.utils.genshi.template import MarkupTemplate
|
||||
from calibre import preferred_encoding
|
||||
from calibre import preferred_encoding, strftime
|
||||
|
||||
|
||||
class Template(MarkupTemplate):
|
||||
@ -126,8 +125,7 @@ class IndexTemplate(Template):
|
||||
def generate(self, title, datefmt, feeds):
|
||||
if isinstance(datefmt, unicode):
|
||||
datefmt = datefmt.encode(preferred_encoding)
|
||||
date = datetime.datetime.now().strftime(datefmt)
|
||||
date = date.decode(preferred_encoding, 'replace')
|
||||
date = strftime(datefmt)
|
||||
return Template.generate(self, title=title, date=date, feeds=feeds)
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user