今宵は月が高い。注意されたし。 -3ページ目

メーラー作りましょ(2) -II

やってみますた 駄目ですた

って言うか、前は %** にエンコードされた URL なんかを SJIS にデコードできる関数があったと思ったのに……まぁ Delphi5 とかあのあたりだったから削除されたのかも知れん

ううむむむむ。

メーラー作りましょ(2)

……昨日のソースだと、何かの理由でメッセージを取り損ねると、それをクリックした時にえらーでますね。まぁ知見できればいいか(うぉぃ


utf-8 でくる subject については今日何やらピンと来たので今から実験するですよ。つまり '=88' とかの '=' をそれぞれ '%' に置き換えたら、Delphiの関数でも処理できるんちゃうかなー? どうかなー?

メーラー作りましょ(1)

ゴーストに乗っけてやろう、というつもりなんですが、とりあえず試作しています。

そうはいっても IdPOP3 べったりですけどね…… ただ IdPOP3 の取得したメールは subject が上手く読めないわけですよ。複数行が読めない。
てなわけで、RetrieveRaw で TStrings に突っ込んでおいて、ヘッダから取り出した情報を一行ずつ変換。あー面倒。

変換には JConvert 使いました。って言うか実質は何もしてない飢餓……JConvert で処理すると、何故か文末に ESC(J が付随するのでそれは削除させています。これで ISO-2022-JP デコードは完璧。

だけどヘッダの UTF-8 のデコードは上手くいきませぬ、一体どうやったらいいのやら。Delphi の UTF 関数はここでは役に立ちまへんヽ(`Д´)ノ


var
  Msg: TStringList;
  Cnt: integer;
  I : integer;
  Wrk: String;
begin
  IdPOP3.Connect;

  Cnt := IdPOP3.CheckMessages;
  for I:=1 to Cnt do begin
    Msg := TStringList.Create;
    if IdPOP3.RetrieveRaw( I, Msg ) then
    begin
      Wrk := GetMailSubject( Msg.Text );
      FMsgList.AddObject( Wrk, Msg )
    end else begin
      Wrk := 'miss of '+IntToStr(I);
      FMsgList.Add( Wrk );
    end;
    
    ListBox1.Items.Add( Wrk );
    StatusBar1.SimpleText := Format( 'read %d of %d ..."%s"', [I,Cnt, Wrk] );

    Application.ProcessMessages;
  end;
    
  IdPOP3.Disconnect;
end;


procedure TForm1.ListBox1Click(Sender: TObject);
var
  Idx: Integer;
  SL : TStrings;
begin
  Editor.Clear;

  Idx := ListBox1.ItemIndex;
  if (Idx = -1) then Exit;

  SL := TStrings(FMsgList.Objects[Idx]);
  Editor.Lines.Text := jconvert.ConvertJCode( SL.Text, SJIS_OUT );
end;


function TForm1.GetMailSubject( Msg:String ): String;
function ConvertShiftJis( Str:String ): String;
begin
  try
    Str := AnsiReplaceText( Str, '===?=', '=?=' );
    Result := jconvert.jis2sjis( jconvert.DecodeHeaderString( Str ) );
  except
    Result := Str;

  end;
end;
function ConvertUTF8( Str:String ): String;
type
  TFunc = function( const A,B: String ): Boolean;
  function TrimEx( F:TFunc; const SubStr:String; var AText:String ): String;
  begin
    if F(SubStr,AText) then Delete( AText,AnsiPos(UpperCase(SubStr),UpperCase(AText)), Length(SubStr) );
  end;
begin
  Str := Trim( Str );
  TrimEx( AnsiStartsText, '=?utf-8?q?', Str );
  TrimEx( AnsiEndsText, '?=', Str );
  Result := Str;
end;
var
  SL : TStringList;
  Idx: Integer;
  I : Integer;
  Wrk: String;
  UPC: String;
  Tmp: Char;
begin
  SL := THashedStringList.Create;
  try
    SL.Text := Msg;
    Idx := SL.IndexOf('');
    for I:=Idx to SL.Count-1 do SL.Delete( Idx );

    Idx := -1;
    for I:=0 to SL.Count-1 do
    begin
      if (Idx = -1) then Idx := IfThen( AnsiStartsText( 'subject:', SL[I] ), I, -1 );
      SL[I] := StringReplace( SL[I], ':', '=', [] );
    end;

    if (Idx > -1) then
    begin
      Result := '';
      Wrk := SL.Values['subject'];

      repeat
        UPC := UpperCase( Wrk );
        if AnsiPos( '=?ISO-2022-JP?B?', UPC )>0 then Wrk := ConvertShiftJis( Wrk )
        else if AnsiPos( '=?UTF-8?Q?', UPC )>0 then Wrk := ConvertUTF8( Wrk );
        
        if AnsiEndsText( #$1B+'(j', Wrk ) then Delete( Wrk, Length(Wrk)-2, 3 );

        Result := Result +Wrk;
        Inc(Idx);
        Wrk := SL[Idx];
        if (Wrk <> '') then Tmp := Wrk[1] else Tmp := #0;
        if (Tmp in [#9,' ']) then Delete( Wrk, 1, 1 );
      until not (Tmp in [#9,' ']) or (Idx = SL.Count-1);
    
    end else
      Result := ConvertShiftJis( SL.Values['subject'] );

  finally
    SL.Free;
  end;
end;

Delphiさんてば素敵……

いや、SAORIはdelphiで作るとSSPと相性が悪いんだって……
ってことはSHIORIも同じことと違うのかなって思っちゃいました……
バグっバグのぷうううう!

手元で作りつつあるメール受信SAORIの方が、精神的ダメージ大きい鴨。

2004-12-21

/*
これがゲームプログラムだったら、伝票が飛んだり、椅子が歩いたりしてもなんの問題もないわけだが。ソフトウェアの設計もTPOを考えないとだめだ、ということなのかもしれない。
*/

むしろゲームだったらそうでもしないと個性差別が出来ない気がする。個性的だったら大概面白いともいえないけど、当たりソフトはそういう中から出てくるわけで、果てはバグですら侮れないコトも。



作業手順は「誰がやっても同じ結果になるように」作成される。これは科学の手法である……または科学的な手法である。「誰がやっても同じ結果になる」ソフトウェアが単純系ゆえに没個性なのはしょうがないかもしんない。

伝票が自分で計算したり飛んでいったり(w したら、外面的には複雑さが縮減されるが内部で複雑になるだけ。複雑になるほど結果が正確に予測しにくくなる。予測通りに結果が出なければ科学的ではない。科学的に作成されない作業手順は現場で混乱を生むか、順調に失敗するかである(マーフィー方式では成功は皆無になる)

正しいプログラムは高度な複合系である時計みたいに出力が単純でなければならないが、ま、趣味のプログラマには関係ない話ですな。