サイト内で配布中のライブラリについてのスレッド。 バグ報告・質問など。 (最新15件の投稿) Atom 1.0

※ブラウザによっては新しい書き込みが表示されない場合があるようなので、返信が表示されていない場合はF5または更新ボタンでページを更新してください。

: ID:cipeco0y

配布中のライブラリについてのバグ報告・要望・質問用のスレッドです。
書き込みの際は再現用のコードやログなどもあわせて書き込んで頂けると助かります。

: ID:F+6R0FE3

>>203
ご参考情報をいただき、ありがとうございました。
たしかに、ExpressMailでは、Move拡張コマンドには対応してないようです。

いずれにしましても、GetMessages(UID配列)により、
対象のメールをまとめて取得することができ、
処理時間が劇的に改善でき、嬉しく思っています。

以上簡単ですが、今後ともよろしくお願いします。

: ID:ucRfKAEb

>>204
いつもお世話になっております。

既知のUIDValidityとUIDから、メッセージを取得する方法について、
処理時間の短縮を検討しています。

現在は、GetMailBoxesメソッドにより、全フォルダを取得した上、
各フォルダについてループさせ、UIDValidityが一致した場合、
そのフォルダから、GetMessageByUidによりメッセージを取得しています。

 foreach (ImapMailboxInfo mailboxInfo in client.GetMailboxes()) {
   ImapOpenedMailboxInfo openedMailbox = client.OpenMailbox(mailboxInfo.FullName);
   if (openedMailbox.UidValidity.ToString().Equals(uidValidity)) {
     ImapMessageInfo message = openedMailbox.GetMessageByUid(int.Parse(uid));
     //メッセージに関する処理
     break;
   }
 }

上記の処理においてフォルダをループさせずに、
直接、UIDValidityから対象フォルダにアクセスする方法はないでしょうか?

 ImapMailboxInfo mailboxInfo in client.GetMailbox(uidValidity);
 

GetMailboxに指定できる引数は、フォルダ名なので、上記は失敗しますが、
このような形で、できないでしょうか?

以上、よろしくお願いします。

: ID:5U/9Z0Js

>>205

UidValidity値は、IDやエイリアスのようなメールボックスを特定するための値ではないため、
UidValidityから対応するメールボックスを取得するような目的には使えません。
ライブラリとしてもそういった機能は提供していません。

従って、挙げられたコードのようにメールボックスをひとつずつ検査してUidValidityを
チェックしていく必要があります。

(UidValidity値は、前回アクセスした時のUIDが現在も有効であるか、つまりメールとUIDの
対応関係が変化していないかどうかをチェックするための値です。 サーバー側の動作により
メールボックスのUidValidity値が変わる場合があります。)

ところで、コード中ではUidValidityの取得のために各メールボックスをOpenしているように
見えますが、GetMailboxesではオプションでメールボックスのステータスも同時に取得することができます。

これによりUidValidityの検証のためにひとつずつメールボックスをOpenする必要がなくなるため、
処理時間の短縮が図れるかもしれません。

 // すべてのメールボックスと、そのステータスを同時に取得する
 foreach (ImapMailboxInfo mailboxInfo in client.GetMailboxes(ImapMailboxListOptions.RequestStatus)) {
   // UidValidity値を検証する
   if (mailboxInfo.UidValidity.ToString().Equals(uidValidity)) {
     // 対象フォルダだった場合は、Openしてメッセージを取得する
     ImapOpenedMailboxInfo openedMailbox = client.OpenMailbox(mailboxInfo.FullName);
     ImapMessageInfo message = openedMailbox.GetMessageByUid(int.Parse(uid));
     //メッセージに関する処理
     break;
   }
 }
: ID:UALUQXu4

>>206

いつも迅速で的確なアドバイスをいただき、
ありがとうございます。

ご教示いただいた方法で、処理時間が半減しました。

また、UidValidity値について、私の認識が誤っていたことも
ご指摘いただき、ありがとうございました。

取り急ぎ、以上です。

: ID:hHO83Hsp

いつもお世話になっております。

今回は、Content-Dispositionヘッダに関して、
各メールソフトでの実装状況についての質問です。

添付ファイル名の判定にあたっては、
Content-Disposition: attachment; の
filenameパラメータを取得するのが基本だと考えています。

ただし、メールソフトによっては、filenameパラメータがなく、
他のパラメータを参考にする必要になる場合があります。

Content-Disposition: attachment; のパラメータには、
filenameパラメータの他に、下記のものがあるようです。

creation-date [RFC2183]
modification-date [RFC2183]
read-date [RFC2183]
size [RFC2183]
name [RFC7578]
voice [RFC2421]
handling [RFC3204]
preview-type [RFC7763]

調べた範囲では、以下のようでした。

【Mozilla Thunderbird】
filenameパラメータのみ

【Microsoft Outlook】
filenameパラメータ
cteation-dateパラメータ
modification-dateパラメータ
sizeパラメータ

他のメールソフトについて、
Content-Disposition: attachment; の実装状況を
ご教示いただければ幸いです。

あくまでも、現在ご存じの情報だけで構いません。

勝手なお願いで恐縮ですが、よろしくお願いします。

: ID:5U/9Z0Js

>>208
ご質問の「Content-Disposition: attachment; の実装状況」とは「filenameパラメータがない場合において、
添付ファイル名の代替として使用されるContent-Dispositionのヘッダパラメータにはどのようなものがあるか」という
趣旨かと推察いたしますが、各メールソフトの添付ファイル名の扱いがどうなっているか、
特にContent-Dispositionパラメータの利用例となると情報を持っていませんので、残念ながら
ご期待に添える回答ができません。

直接の回答にはなりませんが、ライブラリの機能で添付ファイル名を代替的に決定する場合、という観点で
述べると >>156 にてひとつ例示していますので、改めてご覧いただければと思います。

(この例ではサブジェクトをファイル名に使用していますが、ユニークであることの保証が必要なのであれば
Message-IDヘッダやContent-Typeヘッダのboundaryパラメータなどを組み合わせる、あるいは組み合わせた
値からハッシュ値を求めてそれを使う、などがよいかと思います。 ユーザーフレンドリな形式ではありませんが。)

以上、趣意と異なる回答となっていましたらすみません。

: ID:H1apoqUs

>>209

さっそくのご回答ありがとうございます。

各メールソフトの添付ファイル名の扱いについて、
情報をお持ちでないこと、了解しました。

また、根本的な改修の際には、ぜひとも、
>>156 のサンプルを参考にさせていただく所存です。

取り急ぎ以上簡単ですが、今後ともよろしくお願いします。

: ID:AQo2xKr3

こんにちは。
Gmailから、特定の条件に合致するメールを抽出するためのソフトを作りたく、ライブラリを利用させていただいています。
メールやC#の知識は乏しく、ドキュメントを見よう見まねでなんとか動かしている状況です。
本ライブラリを利用してやっていることは、メールのto,from,Body,subject,dateあたりをテキストでローカルDBに保存しておく、というだけの単純なものです。

GetMessagesGmailSearchで取得した
ImapMessageInfo message に対して
message.ReadAs<Mail>(Mail.Load)
を実行すると、一部メールで
'cp932' is an unsupported or invalid charset
という例外が発生します。
どうやらiPhoneから送られたメールの一部がこのような文字コードで送ってくるらしく、Web検索してみるとほかのメーラでも文字化けする現象がよくあるようです。

これは単純にcp932に対応していないため無理だということでしょうか?
それとも何か対応策があるのでしょうか?
>>52に「cp932」というキーワードがあるので関連があるかと思ったのですが、内容が高度で理解できませんでした…

内容的には

var m = inbox.GetMessagesGmailSearch(criteria).ToList();
var count = m.Count;
foreach (var message in m)
  {
    var mail = message.ReadAs<Mail>(Mail.Load);
    if (mail.MimeType.TypeEquals("text"))
    ~~~~~~

というようなコードです。
Smdn.Formats.Mime.dll 0.39.0.0
Smdn.Net.Imap4.Client.dll 1.14.0.0
Smdn.Core.Standards.dll 1.1.0.0
すべて.NET4.5版
を使用しています。
よろしくお願いいたします。

: ID:+LyRQS9z

>>211
ライブラリをご利用いただきありがとうございます。
事象としてはまさに >>52 の方と同様で、対処法は >>23 でも紹介していますが、改めて以下に記載します。

本ライブラリでサポートする文字コードは.NET Frameworkと同じで、.NET FrameworkのEncodingクラスが
サポートしていない場合は今回のように例外が発生します。

本ライブラリでは、このような場合でも代用する文字コード(Encoding)を選択できるようにしています。(>>23)

具体的なコードとしては、まず次のようなメソッドを用意します。

// 代用するEncodingを選択するメソッド
static Encoding SelectFallbackCharset(string encodingName)
{
  if (string.Equals(encodingName, "cp932", StringComparison.OrdinalIgnoreCase)))
  {
    // "cp932"の場合は、CP932の代替としてShift_JISを用いる
    return Encoding.GetEncoding("Shift_JIS");
  }
  else
  {
    // それ以外の非対応文字コードの場合は、nullを返す
    // (例外EncodingNotSupportedException: 'XXX' is an unsupported or invalid charsetをスローする)
    return null;
  }
}

次に、読み込み時にこのメソッドを使うようにMail.Loadの引数で指定します。
ご提示頂いたコードの場合では、ReadAsメソッドの代わりにOpenReadメソッドを使うように変更する必要があります。

var m = inbox.GetMessagesGmailSearch(criteria).ToList();
var count = m.Count;
foreach (var message in m)
{
  Mail mail = null;

  using (var stream = message.OpenRead()) {
    mail = Mail.Load(stream, SelectFallbackCharset);
  }

  if (mail.MimeType.TypeEquals("text"))
    ~~~~~~

このようにすることで、CP932の場合もShift_JISとしてデコードすることができるようになります。

ただこの方法では、CP932をShift_JISとしてデコードすることになるため、特殊文字等で文字化けが
発生する可能性があります。 その点はご留意ください。

もしほかにご不明な点がありましたらお気軽にお問い合わせください。

: ID:AQo2xKr3

>>212
ありがとうございます!
サンプルどころかコピペで済むレベルでコードまで書いていただいて……解説も非常にわかりやすかったです。
頂いたコードで問題なくデコードできることを確認しました。
即日お返事いただきありがとうございました。

: ID:v+9G1zYP

VB版DLLを使用してGmailからImapのメール取得を行っておりますが、
本文が文字化けてしまい上手く取得が出来ません。
以下の書き方に問題はありますでしょうか。

~Clientの定義~
For Each message As ImapMessageInfo In inbox.GetMessages(ImapSearchCriteria.Unseen)
  Dim part As ImapMessagePartInfo
    part = message.MessagePart

  body = part.ReadAllText(ImapMessageFetchBodyOptions.OmitHeader) ←ここで取得した本文が文字化けている
~本文取得後の処理~
: ID:+LyRQS9z

>>214
ライブラリをご利用いただきありがとうございます。

ご提示頂いたコードの場合、ImapMessagePartInfo.ReadAllTextは本文をデコードされていない(生の)状態で返します。

デコードされた状態の本文が必要な場合は、ImapMessageFetchBodyOptions.OmitHeader(ヘッダの省略)と同時に
ImapMessageFetchBodyOptions.DecodeContent(内容のデコード)を組み合わせて指定してください。

なお、デコード動作の詳細についてはドキュメント下記セクションの注釈をご覧ください。
http://smdn.jp/works/libs/Smdn.Net.Imap4.Client/docs/#operation_reference_messagepart_readbody

: ID:v+9G1zYP

>>215
早急な返信ありがとうございます!

デコードされた状態の本文が必要な場合は、ImapMessageFetchBodyOptions.OmitHeader(ヘッダの省略)と同時にImapMessageFetchBodyOptions.DecodeContent(内容のデコード)を組み合わせて指定してください。

とありますが、

ReadAllText(ImapMessageFetchBodyOptions.OmitHeader)

この部分で複数のオプションを組み合わせる方法があるのでしょうか?
複数のオプションを組み合わせる方法が見つけられず
度々の質問となってしまい申し訳ありませんが、ご教示頂けると幸いでございます。

: ID:v+9G1zYP

>>216

上記質問をさせて頂きましたが、
オプションを足し算して、それをImapMessageFetchBodyOptions型にCastすることにより、
複数のオプションが指定できました。

ありがとうございました。

  • 書き込み完了後に投稿内容を編集することは出来ません。
  • >>1と入力すると1番へのアンカーになります。
  • 投稿内容はPukiWiki記法で整形されます。
    • 以下のPukiWiki記法が使えます。
      • 引用文
      • 番号付きリスト、番号なしリスト、定義リスト
      • 整形済みテキスト
        • 複数行のコードブロック・コマンド出力を書き込むには#code{{〜}}、#prompt{{〜}}と記入してください。
        • AAを書き込むには#aa{{〜}}と記入してください。
      • 表組み
      • 見出し
      • 強調・斜体、取り消し線・下線
      • 文字色(&color)、文字サイズ(&size)
      • 注釈
    • URL・メールアドレスは自動的にリンクになります。
    • 詳しくはPukiWikiのFormattingRulesを参照してください。