Link to home
Start Free TrialLog in
Avatar of rikkinorway
rikkinorway

asked on

To create a threaded NNTP news reader

I have created a newsreader with the Indy (10) components, and (almost) everything is going great, so far.
Except for one thing: I can't figure out how to build the message tree in a properly threaded layout (like the most commercial newsreader's do).
I know that the best way to do this, is to make use of the messageID and the reference parameter's, stored in the articleheader, but i can't figure out how. (I know that the reference is a list of messageID's)
I have tried for a long time, but i only get one level of childnodes to a top article (start of thread), and many articles are missing.

I really need a code example now.

(I use a modified TTreeView-component, with the ability of adding columns, so i know how to add nodes/childnodes to it)

Any help will be appreciated!
Avatar of Meldrachaun
Meldrachaun

I'm a little fuzzy on the data you want to transfer across threads.  How is it structured?


Hi,

You can go to http://www.indyproject.org/Sockets/Download/Files/Indy8.en.aspx

and download the demos provided for this old release:

http://www.nevrona.com/indy/downloads/DelphiDemos20010311.zip

There is complete project of newsreader with codesource and a ConnectThread unit. The mainform contains this:

  Procedure OriginalArticleView;
  function ParseXOVERItem(ALine : String) : TListItem;

If I remember well, it doesn't compile with Indy10 but retrieving the messages thread is probably done in the same way.

See if the demo can help you to get the complete level thread for a message.

To retrieve all the items for a particular message, maybe you can use TIdHeaderList.Extract

From the help: TIdHeaderList.Extract finds and stores all values for the given header name.

procedure Extract(const AName: string; ADest: TStrings);

Parameters
const AName: string : Header name to be located and stored.
ADest: TStrings : TStrings to store all located header values.

Description
Extract is a procedure that is used to search the header list for all occurrences of the header in AName. When the header in AName is located, the value of the header is added to ADest. ADest can, as a result, contain multiple values for the named header, with one value per line.
Note: ADest is not cleared prior to use in Extract. Any existing values in ADest are unaffected.


Names is a read-only String property that provides indexed access to header names for the header list. Names works like Borland's TStrings.Names except that it uses the delimiter in NameValueSeparator and respects the case sensitivity flag in CaseSensitive.

Returns the index position of the header with the given name.


function IndexOfName(const Name: string): Integer;

Parameters
const Name: string
Header name to locate.

Returns: Integer - Index position, or -1 when not found.

Description
IndexOfName is an Integer function that returns the index position of the header with the given name. IndexOfName work like Borland's TStrings.IndexOfName except it uses the delimiters defined in NameValueSeparator, and respects the case sensitivity flag in the CaseSensitive property.
IndexOfName can return -1 when the header in Name does not exist in the header list.

Avatar of rikkinorway

ASKER

Thanks bernani, but i just tried that demo with delphi 6, and it doesent thread the articles at all.
The ConnectThread unit is about "threading" (class(TThread)).

It must be my bad english. I'm not talking about that kind of "threading", but to sort newsgroup articles in a hierarchally view, like the most newsreaders do.
Thanks again, but i can get all the header parameters i need with the TIDNNTP1.ParseXOVER - procedure.
The problem is that i don't know how to use them in order to create the message-tree.
A message-ID might look like this: <qKydnntL-bGfPYRVnzvQ@telexxx.com>
A reference is a list of message-ID's:<qKydnntL-bGfPYRVnzvQ@telexxx.com> <xzxzxhczbxyrqb.x.stue@spamurmet.com>
..with the rightmost messageid as last in the thread. (The same for sub-threads within the thread)
The first article in a thread (not sub-thread) do not have a reference - only a messageid. The reference is build when people start to reply to the messages.

Ok, I see.

Have a look at the source of the free xananewsreader:

http://delphi.about.com/od/fullcodeprojects/ss/xananewsreader.htm which implement this functionnality.

Well, i guess i can have a look that one more time. It uses the Zawinsky-algorithm (modified) for article threading, and when i looked at last year, i thought it was to complex to understand. (A function with 5-600 codelines, hashtables and things i didnt know much about at that time).
I was looking for a simpler solution, but i guess that the hard way may be the only way to do this properly.

Thanks!
ASKER CERTIFIED SOLUTION
Avatar of bernani
bernani
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I thank you for all your help, bernani, but i was aware of that article as well. (I can't code in VB)
I know the relationsship between the Message-ID and the references, but i'm still not able to produce Delphi-code out of it!
I have been struggling with this problem for a long time now, and it is time to stop.

You have been very helpful, and i thank you again.