Re: No Indy NNTP client example for Indy9 or 10?

Giganews Newsgroups
Subject: Re: No Indy NNTP client example for Indy9 or 10?
Posted by:  John Mitson (jrm…@hawaii.rr.com)
Date: Sat, 10 Feb 2007

Andrea Raimondi wrote:
> Hello,
>
> I remember that there was an NNTP demo for Indy9, but it's not there in
> the demos I have downloaded from IndyProject.org .
>
> Where can I find it?
>
> Andrew

Andrea,
Here is the source for a NNTP client using Indy 10 that I just started.
  Some of this code came from the demo in Delphi 6.  The commented out
section at the bottom will display messages without attachments and the
"ObtainArticle" procedure will display find attachments and save to the
attached files.  I haven't figured out how to get both attachments (with
or without messages) and messages only.  I can only do one or the other.

Good luck, John

> unit NewsMainUnit;
>
> interface
>
> uses
>  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
>  Dialogs, StdCtrls, ComCtrls, ExtCtrls, IdBaseComponent, IdComponent,
>  IdTCPConnection, IdTCPClient, IdAntiFreezeBase, IdAntiFreeze, IdIntercept,
>  IdSSLOpenSSL, IdExplicitTLSClientServerBase, IdMessageClient, IdNNTP,
>  IdMessage, IdText, ToolWin, IdAttachmentFile, IdAttachmentMemory, ImgList,
>  ActnList;
>
> type
>  TForm1 = class(TForm)
>    ngListBtn: TButton;
>    IdNNTP1: TIdNNTP;
>    IdMessage1: TIdMessage;
>    ListView1: TListView;
>    ListView2: TListView;
>    Splitter1: TSplitter;
>    Memo1: TMemo;
>    StatusBar1: TStatusBar;
>    Button1: TButton;
>    ListView3: TListView;
>    ImageList1: TImageList;
>    ActionList1: TActionList;
>    procedure ngListBtnClick(Sender: TObject);
>    procedure NewsGroupClick(Sender: TObject);
>    procedure ObtainArticle(Sender: TObject);
>    procedure Button1Click(Sender: TObject);
>    procedure ListView3Click(Sender: TObject);
>    //procedure OriginalArticleView;
>  private
>    function ParseXOVERItem(ALine: String): TListItem;
>  public
>    { Public declarations }
>  end;
>
> var
>  Form1: TForm1;
>
> implementation
>
> uses IdSocks;
>
> {$R *.dfm}
>
> procedure TForm1.Button1Click(Sender: TObject);
> var
>  OpenList: TStringList;
>  idx, Hi, Lo: Integer;
>  li: TListItem;
>  NewsGroup, Stat: String;
> begin
>  IdNNTP1.Host := 'enter your host here';
>  IdNNTP1.Port := 119;
>  IdNNTP1.Username := 'jrmit';
>  if Screen.Cursor <> crDefault then
>  begin
>    exit;
>  end;
>  Screen.Cursor := crHourGlass;
>  try
>    if not IdNNTP1.Connected then
>    begin
>      IdNNTP1.Connect;
>    try
>      OpenList := TStringList.Create;
>      try
>        OpenList.LoadFromFile('c:\Newsgroup_list.txt');
>        idx := 0;
>        while idx < 500 {NewsList.Count} do
>        begin
>          li := ListView1.Items.Add;
>          IdNNTP1.ParseNewsGroup(OpenList[idx], NewsGroup, Hi, Lo, Stat);
>          li.Caption := Newsgroup; //first column
>          if (Lo >= Hi) then li.SubItems.Add('None')
>          else
>            li.SubItems.Add(IntToStr(Hi - Lo)); //second column
>            if Length(LowerCase(Stat[1])) > 0 then
>            case Stat[1] of
>              'y' : li.SubItems.Add('Permitted'); //third column
>              'n' : li.SubItems.Add('Read-Only');
>              'm' : li.SubItems.Add('Moderated');
>            end;
>            StatusBar1.SimpleText := Format('Retrieved %d newsgroups', [idx]);
>            Inc (idx);
>          end;
>      finally
>        OpenList.Free;
>      end;
>    except
>      IdNNTP1.Disconnect;
>    end;
>  end
>  else
>  begin
>    IdNNTP1.Disconnect;
>    ListView1.Items.Clear;
>    ListView2.Items.Clear;
>  end;
>  finally Screen.Cursor := crDefault;
>  end;
> end;
>
> procedure TForm1.ngListBtnClick(Sender: TObject);
> var
>  NewsList : TStringList;
>  idx : Integer;
>  Hi, Lo: Integer;
>  li : TListItem;
>  NewsGroup, Stat : String;
> begin
>  IdNNTP1.Host := 'your host';
>  IdNNTP1.Port := 119;
>  IdNNTP1.Username := 'jrmit';
>  if Screen.Cursor <> crDefault then
>  begin
>    exit;
>  end;
>  Screen.Cursor := crHourGlass;
>  try
>    if not IdNNTP1.Connected then
>    begin
>      IdNNTP1.Connect;
>      try
>        NewsList := TStringList.Create;
>        try
>          IdNNTP1.GetNewsgroupList(NewsList);
>          NewsList.SaveToFile('c:\Newsgroup_list.txt');
>          idx := 0;
>          while idx < 500 {NewsList.Count} do
>          begin
>            li := ListView1.Items.Add;
>            IdNNTP1.ParseNewsGroup(NewsList[idx], NewsGroup, Hi, Lo, Stat);
>            li.Caption := Newsgroup; //first column
>            if (Lo >= Hi) then
>              li.SubItems.Add('None')
>            else
>              li.SubItems.Add(IntToStr(Hi - Lo)); //second column
>            if Length(LowerCase(Stat[1])) > 0 then
>            case Stat[1] of
>              'y' : li.SubItems.Add('Permitted'); //third column
>              'n' : li.SubItems.Add('Read-Only');
>              'm' : li.SubItems.Add('Moderated');
>            end;
>            StatusBar1.SimpleText := Format('Retrieved %d newsgroups', [idx]);
>            Inc (idx);
>          end;
>        finally
>          NewsList.Free;
>        end;
>      except
>        IdNNTP1.Disconnect;
>      end;
>    end
>    else
>    begin
>      IdNNTP1.Disconnect;
>      ListView1.Items.Clear;
>      ListView2.Items.Clear;
>    end;
>  finally Screen.Cursor := crDefault;
>  end;
> end;
>
> procedure TForm1.ListView3Click(Sender: TObject);
> begin
>  {display message parts we selected}
>  if ListView3.Selected <> nil then
>  begin
>    if ListView3.Selected.Index > IdMessage1.MessageParts.Count then
>    begin
>      MessageDlg('Unknown index', mtInformation, [mbOK], 0);
>    end else
>    begin
>      showmessage(TIdAttachmentMemory(IdMessage1.MessageParts.Items[ListView3.Selected.Index]).Filename);
>    end;
>  end;
> end;
>
> procedure TForm1.NewsGroupClick(Sender: TObject);
> var
>  idx: Integer;
>  strs: TStringList;
> begin
> strs := TStringList.Create;
>  try
>    IdNNTP1.SelectGroup(ListView1.Selected.Caption);
>    ListView2.Items.Clear;
>    {Get article information from Lowest to Highest articles}
>    IdNNTP1.XOVER(IntToStr(IdNNTP1.MsgLow)+'-'+
>      IntToStr(IdNNTP1.MsgHigh),strs);
>    ListView2.Items.BeginUpdate;
>    try
>      ListView2.Items.Clear;
>      idx := 0;
>      while idx < Strs.Count do begin
>        ParseXOVERItem ( Strs [ idx ] );
>        Inc (idx);
>      end;
>    finally
>      ListView2.Items.EndUpdate;
>    end;
>  finally
>    FreeAndNil(strs);
>  end;
> end;
>
> function TForm1.ParseXOVERItem(ALine: string): TListItem;
> var
>  Subject, From, References, MsgId, ExtraData: string;
>  ArticleIndex, ByteCount, LineCount: Integer;
>  Date: TDateTime;
> begin
>  IdNNTP1.ParseXOVER(ALine, ArticleIndex, Subject, From, Date, MsgId, References,
>    ByteCount, LineCount, ExtraData);
>  Result := ListView2.Items.Add;
>  { Article Index }
>  {We use the data property to store the integer.
>  I know typecasting can be ugly}
>  Result.Data := Pointer(ArticleIndex);
>  { Subject }
>  Result.Caption := Subject;
>  { From }
>  Result.SubItems.Add(From);
>  { Date }
>  Result.SubItems.Add(DateTimeToStr(Date));
>  {Line Count}
>  Result.SubItems.Add(IntToStr(LineCount));
>  {Message ID -workaround because the GetArticle does not seem to work with
>  article indexes}
>  Result.SubItems.Add(MsgId);
> end;
>
> procedure TForm1.ObtainArticle(Sender: TObject);
> var
>  partIdx: Integer;
>  li: TListItem;
> begin
>  if ListView2.Selected <> nil then
>  begin
>    ListView3.Clear;
>    Memo1.Clear;
>    {We to typecast the Selected.Data which is the article index}
>    IdNNTP1.GetArticle(Integer(ListView2.Selected.Data), IdMessage1);
>    //for partIdx := 0 to Pred(IdMessage1.MessageParts.Count) do
>    for partIdx := 0 to IdMessage1.MessageParts.Count - 1 do
>    begin
>      if (IdMessage1.MessageParts.Items[partIdx] is TIdAttachmentFile) then
>      begin //general attachment
>        li := ListView3.Items.Add;
>        li.ImageIndex := 8;
>        li.Caption := TIdAttachmentFile(IdMessage1.MessageParts.Items[partIdx]).Filename;
>        TIdAttachmentFile(IdMessage1.MessageParts.Items[partIdx]).SaveToFile(ExtractFilePath(GetModuleName(hInstance)) +
>        TIdAttachmentFile(IdMessage1.MessageParts.Items[partIdx]).Filename);
>        li.SubItems.Add(TIdAttachmentFile(IdMessage1.MessageParts.Items[partIdx]).ContentType);
>      end else
>      begin //body text
>        if IdMessage1.MessageParts.Items[partIdx] is TIdText then
>        begin
>          Memo1.Lines.Clear;
>          Memo1.Lines.AddStrings(TIdText(IdMessage1.MessageParts.Items[partIdx]).Body);
>        end;
>      end;
>    end;
>  end;
> end;
>
>    {if IdMessage1.MessageParts.Count > 0 then
>    begin
>      for partIdx := 0 to IdMessage1.MessageParts.Count-1 do
>      begin
>        if IdMessage1.MessageParts[partIdx] is TIdText then
>        begin
>          Memo1.Lines.Text :=
>          TIdText(IdMessage1.MessageParts[partIdx]).Body.Text;
>          Exit;
>        end;
>      end;
>    end else
>    Memo1.Lines.Text := IdMessage1.Body.Text;
>  end;}
>
> end.

Replies

In response to

No Indy NNTP client example for Indy9 or 10? posted by Andrea Raimondi on Sat, 10 Feb 2007