From 9ec90a50d4106ad4a41d427e1200642a9efb5bb0 Mon Sep 17 00:00:00 2001 From: Kolan Sh Date: Sat, 24 Mar 2012 23:39:33 +0400 Subject: [PATCH] Automatic character encoding detection in Mercurial repos. --- Gemfile | 2 + lib/redmine/scm/adapters/mercurial_adapter.rb | 42 +++++++++++++++++-- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 13915c6e8..de3e173f3 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,8 @@ gem "builder", "3.0.0" gem "mime-types" gem "awesome_nested_set", "2.1.6" +gem "chardet", ">= 0.9.0" + # Optional gem for LDAP authentication group :ldap do gem "net-ldap", "~> 0.3.1" diff --git a/lib/redmine/scm/adapters/mercurial_adapter.rb b/lib/redmine/scm/adapters/mercurial_adapter.rb index 881fdc89c..dc1300597 100644 --- a/lib/redmine/scm/adapters/mercurial_adapter.rb +++ b/lib/redmine/scm/adapters/mercurial_adapter.rb @@ -17,6 +17,8 @@ require 'redmine/scm/adapters/abstract_adapter' require 'cgi' +require 'rubygems' +require 'UniversalDetector' module Redmine module Scm @@ -255,7 +257,18 @@ module Redmine diff = [] hg *hg_args do |io| io.each_line do |line| - diff << line + iconv_line = line + if !line.nil? + detected = UniversalDetector::chardet(line) + enc = detected['encoding'] + if !enc.nil? + begin + iconv_line = Iconv.conv('UTF-8', enc, line) + rescue Iconv::Failure => err + end + end + end + diff << iconv_line end end diff @@ -267,7 +280,18 @@ module Redmine p = CGI.escape(scm_iconv(@path_encoding, 'UTF-8', path)) hg 'rhcat', '-r', CGI.escape(hgrev(identifier)), hgtarget(p) do |io| io.binmode - io.read + str = io.read + return nil if str.nil? + iconv_str = str + detected = UniversalDetector::chardet(str) + enc = detected['encoding'] + if !enc.nil? + begin + iconv_str = Iconv.conv('UTF-8', enc, str) + rescue Iconv::Failure => err + end + end + return iconv_str end rescue HgCommandAborted nil # means not found @@ -282,7 +306,19 @@ module Redmine next unless line =~ %r{^([^:]+)\s(\d+)\s([0-9a-f]+):\s(.*)$} r = Revision.new(:author => $1.strip, :revision => $2, :scmid => $3, :identifier => $3) - blame.add_line($4.rstrip, r) + str = $4.rstrip + iconv_str = str + if !str.nil? + detected = UniversalDetector::chardet(str) + enc = detected['encoding'] + if !enc.nil? + begin + iconv_str = Iconv.conv('UTF-8', enc, str) + rescue Iconv::Failure => err + end + end + end + blame.add_line(iconv_str, r) end end blame