mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Transliterate filenames before saving to device
This commit is contained in:
parent
47da65b4c9
commit
1c3a870814
@ -10,7 +10,7 @@ from PyQt4.QtGui import QPixmap, QColor, QPainter, QMenu, QIcon, QMessageBox, \
|
|||||||
from PyQt4.QtSvg import QSvgRenderer
|
from PyQt4.QtSvg import QSvgRenderer
|
||||||
|
|
||||||
from calibre import __version__, __appname__, islinux, sanitize_file_name, \
|
from calibre import __version__, __appname__, islinux, sanitize_file_name, \
|
||||||
Settings, iswindows, isosx
|
Settings, iswindows, isosx, preferred_encoding
|
||||||
from calibre.ptempfile import PersistentTemporaryFile
|
from calibre.ptempfile import PersistentTemporaryFile
|
||||||
from calibre.ebooks.metadata.meta import get_metadata, get_filename_pat, set_filename_pat
|
from calibre.ebooks.metadata.meta import get_metadata, get_filename_pat, set_filename_pat
|
||||||
from calibre.devices.errors import FreeSpaceError
|
from calibre.devices.errors import FreeSpaceError
|
||||||
@ -45,6 +45,7 @@ from calibre.ebooks.metadata import MetaInformation
|
|||||||
from calibre.ebooks import BOOK_EXTENSIONS
|
from calibre.ebooks import BOOK_EXTENSIONS
|
||||||
from calibre.ebooks.lrf import preferred_source_formats as LRF_PREFERRED_SOURCE_FORMATS
|
from calibre.ebooks.lrf import preferred_source_formats as LRF_PREFERRED_SOURCE_FORMATS
|
||||||
from calibre.parallel import JobKilled
|
from calibre.parallel import JobKilled
|
||||||
|
from calibre.utils.filenames import ascii_filename
|
||||||
|
|
||||||
class Main(MainWindow, Ui_MainWindow):
|
class Main(MainWindow, Ui_MainWindow):
|
||||||
|
|
||||||
@ -661,10 +662,9 @@ class Main(MainWindow, Ui_MainWindow):
|
|||||||
if not a:
|
if not a:
|
||||||
a = 'Unknown'
|
a = 'Unknown'
|
||||||
prefix = sanitize_file_name(t+' - '+a)
|
prefix = sanitize_file_name(t+' - '+a)
|
||||||
if isinstance(prefix, unicode):
|
if not isinstance(prefix, unicode):
|
||||||
prefix = prefix.encode('ascii', 'ignore')
|
prefix = prefix.decode(preferred_encoding, 'replace')
|
||||||
else:
|
prefix = ascii_filename(prefix)
|
||||||
prefix = prefix.decode('ascii', 'ignore').encode('ascii', 'ignore')
|
|
||||||
names.append('%s_%d%s'%(prefix, id, os.path.splitext(f)[1]))
|
names.append('%s_%d%s'%(prefix, id, os.path.splitext(f)[1]))
|
||||||
remove = [self.library_view.model().id(r) for r in rows] if delete_from_library else []
|
remove = [self.library_view.model().id(r) for r in rows] if delete_from_library else []
|
||||||
self.upload_books(gf, names, good, on_card, memory=(_files, remove))
|
self.upload_books(gf, names, good, on_card, memory=(_files, remove))
|
||||||
|
@ -3,7 +3,7 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
|||||||
|
|
||||||
import StringIO, traceback, sys
|
import StringIO, traceback, sys
|
||||||
|
|
||||||
from PyQt4.Qt import QMainWindow, QString, Qt, QFont
|
from PyQt4.Qt import QMainWindow, QString, Qt, QFont, QCoreApplication, SIGNAL
|
||||||
from calibre.gui2.dialogs.conversion_error import ConversionErrorDialog
|
from calibre.gui2.dialogs.conversion_error import ConversionErrorDialog
|
||||||
from calibre import OptionParser
|
from calibre import OptionParser
|
||||||
|
|
||||||
@ -36,11 +36,17 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
def __init__(self, opts, parent=None):
|
def __init__(self, opts, parent=None):
|
||||||
QMainWindow.__init__(self, parent)
|
QMainWindow.__init__(self, parent)
|
||||||
|
app = QCoreApplication.instance()
|
||||||
|
if app is not None:
|
||||||
|
self.connect(app, SIGNAL('unixSignal(int)'), self.unix_signal)
|
||||||
if getattr(opts, 'redirect', False):
|
if getattr(opts, 'redirect', False):
|
||||||
self.__console_redirect = DebugWindow(self)
|
self.__console_redirect = DebugWindow(self)
|
||||||
sys.stdout = sys.stderr = self.__console_redirect
|
sys.stdout = sys.stderr = self.__console_redirect
|
||||||
self.__console_redirect.show()
|
self.__console_redirect.show()
|
||||||
|
|
||||||
|
def unix_signal(self, signal):
|
||||||
|
print 'Received signal:', repr(signal)
|
||||||
|
|
||||||
def unhandled_exception(self, type, value, tb):
|
def unhandled_exception(self, type, value, tb):
|
||||||
try:
|
try:
|
||||||
sio = StringIO.StringIO()
|
sio = StringIO.StringIO()
|
||||||
|
88
src/calibre/utils/filenames.py
Normal file
88
src/calibre/utils/filenames.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
'''
|
||||||
|
Make strings safe for use as ASCII filenames, while trying to preserve as much
|
||||||
|
meaning as possible.
|
||||||
|
'''
|
||||||
|
|
||||||
|
import re, string
|
||||||
|
|
||||||
|
|
||||||
|
MAP = {
|
||||||
|
u"‘" : u"'",
|
||||||
|
u"’" : u"'",
|
||||||
|
u"«" : u'"',
|
||||||
|
u"»" : u'"',
|
||||||
|
u"…" : u"...",
|
||||||
|
u"№" : u"#",
|
||||||
|
u"Щ" : u"Sch",
|
||||||
|
u"Щ" : u"SCH",
|
||||||
|
u"Ё" : u"Yo",
|
||||||
|
u"Ё" : u"YO",
|
||||||
|
u"Ж" : u"Zh",
|
||||||
|
u"Ж" : u"ZH",
|
||||||
|
u"Ц" : u"Ts",
|
||||||
|
u"Ц" : u"TS",
|
||||||
|
u"Ч" : u"Ch",
|
||||||
|
u"Ч" : u"CH",
|
||||||
|
u"Ш" : u"Sh",
|
||||||
|
u"Ш" : u"SH",
|
||||||
|
u"Ы" : u"Yi",
|
||||||
|
u"Ы" : u"YI",
|
||||||
|
u"Ю" : u"Yu",
|
||||||
|
u"Ю" : u"YU",
|
||||||
|
u"Я" : u"Ya",
|
||||||
|
u"Я" : u"YA",
|
||||||
|
u"Б" : u"B",
|
||||||
|
u"Г" : u"G",
|
||||||
|
u"Д" : u"D",
|
||||||
|
u"И" : u"I",
|
||||||
|
u"Й" : u"J",
|
||||||
|
u"К" : u"K",
|
||||||
|
u"Л" : u"L",
|
||||||
|
u"П" : u"P",
|
||||||
|
u"Ф" : u"F",
|
||||||
|
u"Э" : u"E",
|
||||||
|
u"Ъ" : u"`",
|
||||||
|
u"Ь" : u"'",
|
||||||
|
u"щ" : u"sch",
|
||||||
|
u"ё" : u"yo",
|
||||||
|
u"ж" : u"zh",
|
||||||
|
u"ц" : u"ts",
|
||||||
|
u"ч" : u"ch",
|
||||||
|
u"ш" : u"sh",
|
||||||
|
u"ы" : u"yi",
|
||||||
|
u"ю" : u"yu",
|
||||||
|
u"я" : u"ya",
|
||||||
|
u"б" : u"b",
|
||||||
|
u"в" : u"v",
|
||||||
|
u"г" : u"g",
|
||||||
|
u"д" : u"d",
|
||||||
|
u"з" : u"z",
|
||||||
|
u"и" : u"i",
|
||||||
|
u"й" : u"j",
|
||||||
|
u"к" : u"k",
|
||||||
|
u"л" : u"l",
|
||||||
|
u"м" : u"m",
|
||||||
|
u"н" : u"n",
|
||||||
|
u"о" : u"o",
|
||||||
|
u"п" : u"p",
|
||||||
|
u"т" : u"t",
|
||||||
|
u"ф" : u"f",
|
||||||
|
u"э" : u"e",
|
||||||
|
u"ъ" : u"`",
|
||||||
|
u"ь" : u"'",
|
||||||
|
} #: Translation table
|
||||||
|
|
||||||
|
for c in string.whitespace:
|
||||||
|
MAP[c] = ' '
|
||||||
|
PAT = re.compile('['+u''.join(MAP.keys())+']')
|
||||||
|
print repr('['+u''.join(MAP.keys())+']')
|
||||||
|
|
||||||
|
def ascii_filename(orig):
|
||||||
|
orig = PAT.sub(lambda m:MAP[m.group()], orig)
|
||||||
|
buf = []
|
||||||
|
for i in range(len(orig)):
|
||||||
|
val = ord(orig[i])
|
||||||
|
buf.append('_' if val < 33 or val > 126 else orig[i])
|
||||||
|
return (''.join(buf)).encode('ascii')
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user