Fix showing non-utf8 encoded torrents in add torrent dialog -- this adds an additional dependency on chardet.

This commit is contained in:
Andrew Resch 2009-05-09 17:46:13 +00:00
parent 96c399f7f5
commit 384eee2744
2 changed files with 38 additions and 10 deletions

1
README
View File

@ -54,6 +54,7 @@ Dependencies:
pygtk >= 2.10 pygtk >= 2.10
librsvg librsvg
xdg-utils xdg-utils
chardet
Web: Web:
mako mako

View File

@ -1,9 +1,9 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# deluge/ui/common.py # deluge/ui/common.py
# #
# Copyright (C) Damien Churchill 2008 <damoxc@gmail.com> # Copyright (C) Damien Churchill 2008 <damoxc@gmail.com>
# Copyright (C) Andrew Resch 2009 <andrewresch@gmail.com>
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -24,18 +24,39 @@
import os import os
import sys import sys
import urlparse
try: try:
from hashlib import sha1 as sha from hashlib import sha1 as sha
except ImportError: except ImportError:
from sha import sha from sha import sha
import urlparse
from deluge import bencode from deluge import bencode
from deluge.log import LOG as log from deluge.log import LOG as log
import deluge.configmanager import deluge.configmanager
def decode_string(s, encoding="utf8"):
"""
Decodes a string and re-encodes it in utf8. If it cannot decode using
`:param:encoding` then it will try to detect the string encoding and
decode it.
:param s: str to decode
:param encoding: str, the encoding to use in the decoding
"""
try:
s = s.decode(encoding).encode("utf8")
except UnicodeDecodeError:
try:
import chardet
except ImportError:
s = s.decode(encoding, "replace").encode("utf8")
else:
s = s.decode(chardet.detect(s)["encoding"]).encode("utf8")
return s
class TorrentInfo(object): class TorrentInfo(object):
def __init__(self, filename): def __init__(self, filename):
# Get the torrent data from the torrent file # Get the torrent data from the torrent file
@ -52,16 +73,22 @@ class TorrentInfo(object):
self.encoding = "UTF-8" self.encoding = "UTF-8"
if "encoding" in self.__m_metadata: if "encoding" in self.__m_metadata:
self.encoding = self.__m_metadata["encoding"] self.encoding = self.__m_metadata["encoding"]
elif "codepage" in self.__m_metadata:
self.encoding = str(self.__m_metadata["codepage"])
# We try to decode based on the encoding found and if we can't, we try
# to detect the encoding and decode that
self.__m_name = decode_string(self.__m_metadata["info"]["name"], self.encoding)
# Get list of files from torrent info # Get list of files from torrent info
paths = {} paths = {}
if self.__m_metadata["info"].has_key("files"): if self.__m_metadata["info"].has_key("files"):
prefix = "" prefix = ""
if len(self.__m_metadata["info"]["files"]) > 1: if len(self.__m_metadata["info"]["files"]) > 1:
prefix = self.__m_metadata["info"]["name"].decode(self.encoding, "replace").encode("utf8") prefix = self.__m_name
for index, f in enumerate(self.__m_metadata["info"]["files"]): for index, f in enumerate(self.__m_metadata["info"]["files"]):
path = os.path.join(prefix, *f["path"]).decode(self.encoding, "replace").encode("utf8") path = decode_string(os.path.join(prefix, *f["path"]))
f["index"] = index f["index"] = index
paths[path] = f paths[path] = f
@ -75,24 +102,24 @@ class TorrentInfo(object):
self.__m_files_tree = file_tree.get_tree() self.__m_files_tree = file_tree.get_tree()
else: else:
self.__m_files_tree = { self.__m_files_tree = {
self.__m_metadata["info"]["name"].decode(self.encoding, "replace").encode("utf8"): (self.__m_metadata["info"]["length"], True) self.__m_name: (self.__m_metadata["info"]["length"], True)
} }
self.__m_files = [] self.__m_files = []
if self.__m_metadata["info"].has_key("files"): if self.__m_metadata["info"].has_key("files"):
prefix = "" prefix = ""
if len(self.__m_metadata["info"]["files"]) > 1: if len(self.__m_metadata["info"]["files"]) > 1:
prefix = self.__m_metadata["info"]["name"].decode(self.encoding, "replace").encode("utf8") prefix = self.__m_name
for f in self.__m_metadata["info"]["files"]: for f in self.__m_metadata["info"]["files"]:
self.__m_files.append({ self.__m_files.append({
'path': os.path.join(prefix, *f["path"]).decode(self.encoding, "replace").encode("utf8"), 'path': decode_string(os.path.join(prefix, *f["path"])),
'size': f["length"], 'size': f["length"],
'download': True 'download': True
}) })
else: else:
self.__m_files.append({ self.__m_files.append({
"path": self.__m_metadata["info"]["name"].decode(self.encoding, "replace").encode("utf8"), "path": self.__m_name,
"size": self.__m_metadata["info"]["length"], "size": self.__m_metadata["info"]["length"],
"download": True "download": True
}) })
@ -108,7 +135,7 @@ class TorrentInfo(object):
@property @property
def name(self): def name(self):
return self.__m_metadata["info"]["name"].decode(self.encoding).encode("utf8") return self.__m_name
@property @property
def info_hash(self): def info_hash(self):