사이드바의 mutt 그리스어 문자(Offlineimap을 통해 얻은 메일함 이름)

사이드바의 mutt 그리스어 문자(Offlineimap을 통해 얻은 메일함 이름)

바보~의사이드바, 그리스 문자(그리스 문자로 이름이 지정된 메일박스)는 올바르게 읽을 수 없습니다. 어쨌든 둘 다 내부에는 그런 문제가 없습니다.색인 및 호출기, 그리스어 문자/단어/이름이 잘 표시됩니다.

                        여기에 이미지 설명을 입력하세요.

Giles가 댓글을 작성한 후 업데이트되었습니다.

문제의 설정은 IMAP 서버에서 이메일 읽기/쓰기를 포함하여 두 가지 다른 시스템(Funtoo 및 GNU bash, 버전 4.2.45(1) 릴리스를 실행하는 워크스테이션과 노트북)에 대한 것입니다. Enter email mutt. 응답 은 다음 locale과 같습니다

LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE=POSIX
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

그리고 mutt의 구성 파일에는 로케일 변수가 설정되어 있지 않습니다.

메시지는 실제로 다음을 통해 동기화됩니다.오프라인 지도다음을 사용하여 보냅니다.접미사.오프라인 지도, mutt의 구성 파일 중 하나에서 파생된 파일(즉, 이름이 지정된 파일)에 메일함(이름) 목록을 기록합니다 mailboxes(표시됨 source ~/.mutt/mailboxes). 파일 내용을 살펴보니 mailboxes그리스 이름이 '오해'된 것으로 드러났다.

그럼에도 불구하고 그리스 이름은 동일한 IMAP 서버와 의심스러운 사서함에 액세스한 웹 메일 클라이언트(RoundCube)를 통해 정상적으로 표시되었습니다.

질문

  • 왜 이런 일이 발생합니까?
  • offlineimap구성 오류 인가요 ?
  • 어떻게 해결하나요?

남은 질문은?[2015년 3월] (아래 답변도 참조)

그러나 로컬 저장소 폴더 이름(디렉터리 이름)은 읽을 수 없는 상태로 유지됩니다. 즉, 위에 표시된 그리스어 폴더 이름(Yποτροψα)은 실제로 디렉터리입니다 &A6UDwAO,A8QDwQO,A8YDrwOx-.이는 동기화 도중이 아니라 폴더 이름과 메시지가 동기화된 후에 폴더 이름 변환이 발생한다는 의미입니까? 또는,이 디렉터리를 삭제해야 합니까?(로컬 저장소에서)Offlineimap을 통해 또 다른 동기화를 강제합니다.(해당 메일박스 폴더가 원격 저장소에서 삭제되지 않도록 주의하세요)?

답변1

요컨대,

"문제"는 다음과 같은 사실에서 발생합니다.IMAP4는 수정된 UTF-7 인코딩을 사용하여 폴더 이름을 인코딩합니다..오프라인 지도로컬 저장소가 생성되기 전에 폴더 이름은 읽을 수 있는 이름(예: UTF-8 형식)으로 변환되지 않습니다. 그러면 이 질문의 스크린샷에 표시된 것과 같이 읽을 수 없는 폴더 이름이 파생됩니다. 그러므로 둘 다 아니다.바보...도 아니다오프라인 지도부적절한 취급 또는 잘못된 구성 자체.

다음 블로그 게시물과 git 저장소에서는 이 문제를 자세히 논의하고 해결합니다.

해결책

본질적으로,파이썬 스크립트(아래 제공됨)은 오프라인imap의 구성 파일에 입력할 수 있도록 사람이 읽을 수 있는 폴더 이름을 내보내는 데 도움이 됩니다(예 offlineimaprc:오프라인 IMAP 매뉴얼). 또한 올바른 폴더 이름 변환(python 스크립트에 정의된 함수 사용)을 위한 유익한 코드 줄이 있습니다.

# Name translation from UTF7 to UTF8
nametrans = lambda foldername: foldername.decode('imap4-utf-7').encode('utf-8')

원격 저장소 옵션 섹션 아래의 오프라인imap 구성 파일에 추가되었습니다.

업데이트(2015년 4월)

또 다른 규칙은필수의역동작 참조폴더 필터링 및 이름 번역. 지침은 다음과 같습니다.

# Name translation, reverse!
nametrans = lambda foldername: foldername.decode('utf-8').encode('imap4-utf-7')

mailboxes파일에서는 오프라인imap으로 생성된 그리스어 이름이 올바르게 표시됩니다. 이렇게 하면 mutt 내부의 문제가 해결되고 폴더 이름이 예상대로 나타납니다(이 경우 그리스 이름).여기에 이미지 설명을 입력하세요.


남은 질문은?

그러나 로컬 저장소 폴더 이름(디렉터리 이름)은 읽을 수 없는 상태로 유지됩니다. 즉, 위에 표시된 그리스어 폴더 이름(Yποτροψα)은 실제로 디렉터리입니다 &A6UDwAO,A8QDwQO,A8YDrwOx-.이는 동기화하는 동안이 아니라 폴더 이름과 메시지가 동기화된 후에 폴더 이름 변환이 발생한다는 의미입니까? 또는,이 디렉터리를 삭제해야 합니까?(로컬 저장소에서)Offlineimap을 통해 또 다른 동기화를 강제합니다.(해당 메일박스 폴더가 원격 저장소에서 삭제되지 않도록 주의하세요)?


국제 이메일 이름(IMAP, UTF-7)을 처리하는 Python 스크립트:

# vim:fileencoding=utf-8

r"""
Imap folder names are encoded using a special version of utf-7 as defined in RFC
2060 section 5.1.3.

From: http://piao-tech.blogspot.com/2010/03/get-offlineimap-working-with-non-ascii.html

5.1.3.  Mailbox International Naming Convention

   By convention, international mailbox names are specified using a
   modified version of the UTF-7 encoding described in [UTF-7].  The
   purpose of these modifications is to correct the following problems
   with UTF-7:

    1) UTF-7 uses the "+" character for shifting; this conflicts with
     the common use of "+" in mailbox names, in particular USENET
     newsgroup names.

    2) UTF-7's encoding is BASE64 which uses the "/" character; this
     conflicts with the use of "/" as a popular hierarchy delimiter.

    3) UTF-7 prohibits the unencoded usage of "\"; this conflicts with
     the use of "\" as a popular hierarchy delimiter.

    4) UTF-7 prohibits the unencoded usage of "~"; this conflicts with
     the use of "~" in some servers as a home directory indicator.

    5) UTF-7 permits multiple alternate forms to represent the same
     string; in particular, printable US-ASCII chararacters can be
     represented in encoded form.

   In modified UTF-7, printable US-ASCII characters except for "&"
   represent themselves; that is, characters with octet values 0x20-0x25
   and 0x27-0x7e.  The character "&" (0x26) is represented by the two-
   octet sequence "&-".

   All other characters (octet values 0x00-0x1f, 0x7f-0xff, and all
   Unicode 16-bit octets) are represented in modified BASE64, with a
   further modification from [UTF-7] that "," is used instead of "/".
   Modified BASE64 MUST NOT be used to represent any printing US-ASCII
   character which can represent itself.

   "&" is used to shift to modified BASE64 and "-" to shift back to US-
   ASCII.  All names start in US-ASCII, and MUST end in US-ASCII (that
   is, a name that ends with a Unicode 16-bit octet MUST end with a "-
   ").

    For example, here is a mailbox name which mixes English, Japanese,
    and Chinese text: ~peter/mail/&ZeVnLIqe-/&U,BTFw-

"""

import binascii
import codecs

# encoding
def modified_base64(s):
  s = s.encode('utf-16be')
  return binascii.b2a_base64(s).rstrip(b'\n=').replace(b'/', b',').decode('ascii')

def doB64(_in, r):
  if _in:
    r.append('&%s-' % modified_base64(''.join(_in)))
    del _in[:]

def encoder(s):
  r = []
  _in = []
  for c in s:
    ordC = ord(c)
    if 0x20 <= ordC <= 0x25 or 0x27 <= ordC <= 0x7e:
      doB64(_in, r)
      r.append(c)
    elif c == '&':
      doB64(_in, r)
      r.append('&-')
    else:
      _in.append(c)
  doB64(_in, r)
  return (''.join(r).encode('ascii'), len(s))

# decoding
def modified_unbase64(s):
  b = binascii.a2b_base64(s.replace(b',', b'/') + b'===')
  return str(b, 'utf-16be')

def decoder(s):
  r = []
  decode = []
  for c in s:
    if c == b'&' and not decode:
      decode.append(b'&')
    elif c == b'-' and decode:
      if len(decode) == 1:
        r.append('&')
      else:
        r.append(modified_unbase64(b''.join(decode[1:])))
      decode = []
    elif decode:
      decode.append(c)
    else:
      r.append(c.decode('ascii'))
  if decode:
    r.append(modified_unbase64(b''.join(decode[1:])))
  bin_str = ''.join(r)
  return (bin_str, len(s))

class StreamReader(codecs.StreamReader):
  def decode(self, s, errors='strict'):
    return decoder(s)

class StreamWriter(codecs.StreamWriter):
  def decode(self, s, errors='strict'):
    return encoder(s)

def imap4_utf_7(name):
  if name == 'imap4-utf-7':
    return (encoder, decoder, StreamReader, StreamWriter)

codecs.register(imap4_utf_7)

관련 정보