Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Request help with 40tude dialog program syntax

13 views
Skip to first unread message

Stijn De Jong

unread,
Dec 31, 2016, 2:40:37 PM12/31/16
to
I'm not a programmer where I'm just trying to meld two different
onBeforeSendingMessage scripts found in the 40tude script repository
(http://dialog.datalist.org/scripts).

I can put the two scripts together, but I can't redefine the variable.
The variable seems to take one and only one value!

That is, I can easily give the variable any value, but I can't seem to
figure out the syntax to *redefine* that variable in an "if" statement.

This pseudocode tries to explain what I'm trying to accomplish:
if identity = id1 then
Remove_Headers='User-Agent: ,Message-ID: ';
else if identity = id2 then
Remove_Headers='User-Agent: ,Content-Transfer-Encoding: ';
else
Remove_Headers='User-Agent: ,Mime-Version: ';

To help you help me, I'll post the exact code I'm using, but at the risk of
confusing things (because the code is a few hundred lines long).

Essentially, all I'm trying to do is set the headers based on the identity.
Nothing more fancy than that.

I'm asking for syntax help because everything I try, by trial and error,
has caused an error, simply because I don't know how to redefine the
RemoveHeader variable syntactically.

Stijn De Jong

unread,
Dec 31, 2016, 2:50:54 PM12/31/16
to
Op Sat, 31 Dec 2016 20:40:28 +0100, Stijn De Jong schreef:

> To help you help me, I'll post the exact code I'm using, but at the risk of
> confusing things (because the code is a few hundred lines long).

This is the code I am using which sets the identity.
http://dialog.datalist.org/scripts/CheckingIdentity.html

This is the code I am using which removes the headers:
http://dialog.datalist.org/scripts/RemoveHeaders.html

All I'm trying to do is meld the two, where the outgoing headers to be
removed depend on the identity of the sender.

Rodney Pont

unread,
Dec 31, 2016, 3:00:27 PM12/31/16
to
On Sat, 31 Dec 2016 20:40:28 +0100, Stijn De Jong wrote:

>This pseudocode tries to explain what I'm trying to accomplish:
>if identity = id1 then
> Remove_Headers='User-Agent: ,Message-ID: ';
>else if identity = id2 then
> Remove_Headers='User-Agent: ,Content-Transfer-Encoding: ';
> else
> Remove_Headers='User-Agent: ,Mime-Version: ';

Try;
if identity == id1 then
Remove_Headers='User-Agent: ,Message-ID: ';
else if identity == id2 then
Remove_Headers='User-Agent: ,Content-Transfer-Encoding: ';
else
Remove_Headers='User-Agent: ,Mime-Version: ';

= is an assignment operator, it makes the left side = to the right
side, you need the double = for a comparison.

I'm not familiar with the scripting you are using but that's worth
trying.

--
Faster, cheaper, quieter than HS2
and built in 5 years;
UKUltraspeed <http://www.500kmh.com/>


Stijn De Jong

unread,
Dec 31, 2016, 3:01:23 PM12/31/16
to
Op Sat, 31 Dec 2016 20:50:46 +0100, Stijn De Jong schreef:

> This is the code I am using which sets the identity.
> http://dialog.datalist.org/scripts/CheckingIdentity.html
>
> This is the code I am using which removes the headers:
> http://dialog.datalist.org/scripts/RemoveHeaders.html
>
> All I'm trying to do is meld the two, where the outgoing headers to be
> removed depend on the identity of the sender.

At the risk of confusing the issue, here is the current code that was used
to send this message, which has no syntax errors, and which sort of works
but which allows only a single static setting for the remove headers
variable.

All I'm trying to do is add the simple decision below:

if identity = id1 then
Remove_Headers='User-Agent: ,Message-ID: ';
else if identity = id2 then
Remove_Headers='User-Agent: ,Content-Transfer-Encoding: ';
else
Remove_Headers='User-Agent: ,Mime-Version: ';

------- cut here for the current working code --------
program OnBeforeSendingMessage;
RemoveFromEmails = true;
RemoveFromNews = true;

procedure RemoveHeaders ( Message : TStringlist;
IsEmail : boolean
);
var i : integer;
k : integer;
s : string;
CommaPos : integer;
DelHeader : TStringlist;
RemoveH : String;
begin
RemoveH := Remove_Headers;
i := 0;
if ((IsEmail=true) and (RemoveFromEmails=true)) or
((IsEmail=false) and (RemoveFromNews=true)) then begin
If ( RemoveH <> '' ) then begin
try
DelHeader := TStringlist.Create;
if ansipos ( ',', RemoveH) = 0 then begin
DelHeader.Add ( LowerCase ( TrimLeft( RemoveH )));
end // if
else begin
CommaPos := 0;
for k := 1 to length ( RemoveH ) do begin
If RemoveH[k] = ',' then begin
DelHeader.Add ( LowerCase ( TrimLeft (copy ( RemoveH,
CommaPos + 1, k - ( CommaPos + 1 )))));
CommaPos := k;
end; // if
if k = length ( RemoveH ) then
DelHeader.Add ( LowerCase ( TrimLeft (copy ( RemoveH,
CommaPos + 1, k - CommaPos ))));
end; // for
end; // else
s:=Message.text;
while (Message.Strings[i]<>'') do begin
k := 0;
while k <= ( DelHeader.Count - 1 ) do begin
if pos( DelHeader[k], LowerCase ( Message.Strings[i] )) = 1
then begin
delete ( s, pos(DelHeader[k], LowerCase (s) ), length (
Message.Strings[i] ) + 2 );
i := i - 1;
k := DelHeader.Count - 1;
message.text := s;
end; // if
k := k + 1;
end; // while
i := i + 1;
end; //while
message.text:=s;
finally
DelHeader.Free;
end; // try - finally
end; // if
end; // if
end; // RemoveHeaders

function StrMatch(str: String; pattern: String):Boolean;
var
patternSize : Integer;
subStr : String;
compareRes : Integer;
begin
patternSize := Length(pattern);
subStr := Copy(str, 1, patternSize);
compareRes := CompareStr(pattern, subStr);
if (compareRes = 0) then
result := true
else
result := false;
end;

function From2Identity(from: String): String;
begin
if (StrMatch(from, 'First1 Last1 <ema...@domain.com>')) then
result := 'id1'
else if (StrMatch(from, 'First2 Last2 <ema...@domain.com>')) then
result := 'id2'
else
result := 'unknown';
end;

function NewsGroup2Identity(newsgroup: String): String;
begin
if (StrMatch(newsgroup, 'news.software.readers') or
StrMatch(newsgroup, 'alt.free.newsservers')) then
result := 'id1'
else
result := 'id2';
end;
// The server identity doesn't seem to play any role in the decision.
// So I'm not sure why this is needed (but it's required).
function Server2Identity(server: String): String;
begin
if (CompareStr(server, 'aioe') = 0) then
result := 'id1'
else
result := 'id2';
end;

function BadIdentity(): boolean;
begin
result := false;
end;

function CheckIdentity(var message: TStringlist; servername: string;
isEmail: boolean):boolean;
var
fromIdentity : String;
newsgroupIdentity : String;
serverIdentity : String;
i : Integer;
begin
if (not IsEmail) then
begin
for i := 0 to Message.Count - 1 do
begin
if (strMatch(Message[i], 'From:')) then
fromIdentity := Copy(Message[i], 7, Length(Message[i]) - 6);
if (strMatch(Message[i], 'Newsgroups:')) then
newsgroupIdentity := Copy(Message[i], 13, Length(Message[i]) - 12);
end;
fromIdentity := From2Identity(fromIdentity);
newsgroupIdentity := NewsGroup2Identity(newsgroupIdentity);
serverIdentity := Server2Identity(servername);
// The lines below write to the log file ./40tude/logs/20161231.log
WriteToLog(' fromIdentity = ' + fromIdentity, 7);
WriteToLog(' newsgroupIdentity = ' + newsgroupIdentity, 7);
WriteToLog(' serverIdentity = ' + serverIdentity, 7);
if ((CompareStr(fromIdentity, newsgroupIdentity) = 0) and
(CompareStr(newsgroupIdentity, serverIdentity) = 0)) then
result := true
else
result := BadIdentity();
end
else
result := true;
end;

function OnBeforeSendingMessage(var Message : TStringlist;
Servername : string;
IsEmail : boolean
):boolean;
begin
// Added the result line below:
result := CheckIdentity(message, servername, isEmail);
RemoveHeaders(Message,IsEmail);
result:=true;
end;
// ----------------------------------------------------------------------
begin
end.
------- cut here for the current working code --------

Rodney Pont

unread,
Dec 31, 2016, 3:15:25 PM12/31/16
to
On Sat, 31 Dec 2016 20:50:46 +0100, Stijn De Jong wrote:

>This is the code I am using which sets the identity.
>http://dialog.datalist.org/scripts/CheckingIdentity.html
>
>All I'm trying to do is meld the two, where the outgoing headers to be
>removed depend on the identity of the sender.

I looked at the setting identity script so try
if (identity = id1) then
Remove_Headers := 'User-Agent: ,Message-ID: ';
else (if identity = id2) then
Remove_Headers := 'User-Agent: ,Content-Transfer-Encoding: ';
else
Remove_Headers := 'User-Agent: ,Mime-Version: ';


Your sample script has the comparison in brackets and used := as
assignment. It also appears to not use semicolon for line ending after
a then if there is an else following but does after the else.

Does id1 and id2 need to be in quotes, 'id1' 'id2'

Stijn De Jong

unread,
Dec 31, 2016, 3:20:17 PM12/31/16
to
Op Sat, 31 Dec 2016 20:00:07 +0000 (GMT), Rodney Pont schreef:

> Try;
> if identity == id1 then
> Remove_Headers='User-Agent: ,Message-ID: ';
> else if identity == id2 then
> Remove_Headers='User-Agent: ,Content-Transfer-Encoding: ';
> else
> Remove_Headers='User-Agent: ,Mime-Version: ';
>
> = is an assignment operator, it makes the left side = to the right
> side, you need the double = for a comparison.
>
> I'm not familiar with the scripting you are using but that's worth
> trying.

Thanks for that prompt help (which I realize came before I added the actual
scripts that I was melding).

I don't think the "if" sytax is my mental problem here (it may be a problem
later, but not just yet).

I think there is a "rule" that I don't understand which doesn't allow me to
redefine the Remove_Headers variable (or constant, as it seems to be).

For example, this works:
const
Remove_Headers='User-Agent: ,Message-ID: ';

But this fails:
https://i.imgsafe.org/811a9201c9.jpg

Just redefining the variable fails with a "duplicate identifier" error:
const
Remove_Headers='User-Agent: ,Message-ID: ';
Remove_Headers='User-Agent: ,Mime-Version: ';

This also fails with a "duplicte identifier" error:
const
Remove_Headers='User-Agent: ,Message-ID: ';
const
Remove_Headers='User-Agent: ,Mime-Version: ';

If I remove the "const", it complains of a different error, so, the const
is apparently required.
https://i.imgsafe.org/811aae6f99.jpg

All I'm asking, really, is how to re-define the variable "Remove_Headers".

Stijn De Jong

unread,
Dec 31, 2016, 3:45:16 PM12/31/16
to
Op Sat, 31 Dec 2016 20:11:30 +0000 (GMT), Rodney Pont schreef:

> Does id1 and id2 need to be in quotes, 'id1' 'id2'

I do not know, but my plan was to define the Remove_Headers variable at the
time that the identity was determined, so that I wouldn't even need an if
statement at that very moment.

But when I do that, I get the error that the Remove_Headers is a duplicate!

This is the original that works without the Remove_Header variable:
https://i.imgsafe.org/817947489d.jpg

function From2Identity(from: String): String;
begin
if (StrMatch(from, 'Stijn De Jong <stijnd...@nlnet.nl>')) then
result := 'id1'
else if (StrMatch(from, 'First1 Last2 <ema...@domain.com>')) then
result := 'id2'
else
result := 'unknown';
end;

This is the same as above, but with the Remove_Header inserted:
https://i.imgsafe.org/8182381b0a.jpg

function From2Identity(from: String): String;
begin
if (StrMatch(from, 'Stijn De Jong <stijnd...@nlnet.nl>')) then
result := 'id1'
Remove_Headers := 'User-Agent: ,Message-ID: ';
else if (StrMatch(from, 'First1 Last2 <ema...@domain.com>')) then
result := 'id2'
Remove_Headers := 'User-Agent: ,Content-Transfer-Encoding: ';
else
result := 'unknown';
Remove_Headers := 'User-Agent: ,Mime-Version: ';
end;

What I can't mentally fathom yet is why I can't just re-define the variable
"Remove_Header" at any point whatsoever in the script.

That's really where I think I'm most stumbled.

Rodney Pont

unread,
Dec 31, 2016, 3:45:26 PM12/31/16
to
On Sat, 31 Dec 2016 21:20:09 +0100, Stijn De Jong wrote:

>I think there is a "rule" that I don't understand which doesn't allow me to
>redefine the Remove_Headers variable (or constant, as it seems to be).
>
>For example, this works:
> const
> Remove_Headers='User-Agent: ,Message-ID: ';
>
>But this fails:
>https://i.imgsafe.org/811a9201c9.jpg
>
>Just redefining the variable fails with a "duplicate identifier" error:
> const
> Remove_Headers='User-Agent: ,Message-ID: ';
> Remove_Headers='User-Agent: ,Mime-Version: ';
>
>This also fails with a "duplicte identifier" error:
> const
> Remove_Headers='User-Agent: ,Message-ID: ';
> const
> Remove_Headers='User-Agent: ,Mime-Version: ';
>
>If I remove the "const", it complains of a different error, so, the const
>is apparently required.
> https://i.imgsafe.org/811aae6f99.jpg
>
>All I'm asking, really, is how to re-define the variable "Remove_Headers".

For a start if you define it as a constant it's not a variable and
can't(shouldn't) be redefined. I don't recognise the syntax of this
scripting language so I'm guessing a bit(lot) :-)

It looks as if you define a string as

Remove_Headers : String
in the var section.

If you want to use that variable outside of a function don't define it
within a function call, you need to define it at the beginning of the
script so that it has global context. If it's defined within a function
call it only has context within that function and the value will not be
carried outside of it.

I can't tell you exactly what to do since I can't follow the code, I've
got CFS/ME and my short term memory isn't any good, I can follow a few
lines but no more, the earlier lines have just left me.

Stijn De Jong

unread,
Dec 31, 2016, 3:52:02 PM12/31/16
to
Op Sat, 31 Dec 2016 20:00:07 +0000 (GMT), Rodney Pont schreef:

> Try;
> if identity == id1 then
> Remove_Headers='User-Agent: ,Message-ID: ';
> else if identity == id2 then
> Remove_Headers='User-Agent: ,Content-Transfer-Encoding: ';
> else
> Remove_Headers='User-Agent: ,Mime-Version: ';
>
> = is an assignment operator, it makes the left side = to the right
> side, you need the double = for a comparison.
>
> I'm not familiar with the scripting you are using but that's worth
> trying.

I'm not familiar with the scripting syntax either. :)
I don't understand why I can't redefine the variable "Remove_Headers".

Here's what happens when I use the suggested syntax above:
https://i.imgsafe.org/819a434db8.jpg

function From2Identity(from: String): String;
begin
if (StrMatch(from, 'Stijn De Jong <stijnd...@nlnet.nl>')) then
result := 'id1'
Remove_Headers='User-Agent: ,Message-ID: ';
else if (StrMatch(from, 'First2 Last2 <ema...@domain.com>')) then
result := 'id2'
Remove_Headers='User-Agent: ,Content-Transfer-Encoding: ';
else
result := 'unknow';
Remove_Headers='User-Agent: ,Mime-Version: ';
end;

Stijn De Jong

unread,
Dec 31, 2016, 4:08:19 PM12/31/16
to
Op Sat, 31 Dec 2016 20:43:21 +0000 (GMT), Rodney Pont schreef:

> For a start if you define it as a constant it's not a variable and
> can't(shouldn't) be redefined. I don't recognise the syntax of this
> scripting language so I'm guessing a bit(lot) :-)

I understand.
The scripting language is foreign to me too. :)

Each of the scripts works alone, so all I was really trying to do was meld
them so that I could redefine the "thing" that is "Remove_Headers" based on
the identity which appears to be either "id1" or "id2" as shown in the log
file from my last post:
3 13411140: Sending message to alt.windows7.general,news.software.readers
(Started) [$00000F44]
3 13411140: Connecting to NNTP (SSL) news.mixmin.net:563 [$00000F44]
7 13413796: fromIdentity = id1
7 13413796: newsgroupIdentity = id2
7 13413796: serverIdentity = id2
3 13413781: Connected to NNTP news.mixmin.net:563 [$00000F44]
3 13413781: Posting message to NNTP server [$00000F44]
3 13414781: Posting sent successfully: Article received
<o495ph$1t8$1...@news.mixmin.net>; (Finished) [$00000F44]

> It looks as if you define a string as
>
> Remove_Headers : String
> in the var section.

I don't see a "section" for variables, but I think I agree with you that at
some point we simply define the variable "Remove_Headers".

I've defined it in a variety of places in the script and if I only define
it once, it seems to work. But my whole point is to define it based on the
identity (either id1 or id2) which is where I get the errors.

> If you want to use that variable outside of a function don't define it
> within a function call, you need to define it at the beginning of the
> script so that it has global context.

I can define the variable Remove_Headers almost anywhere, but I seem to
only be able to do that once. If I later redefine it inside of the
procedure that determines if it's id1 or id2 that is posting, then the
redefinition of Remove_Headers always fails with a duplicate identifier
error.

That's really my block that is stumbling me!

> If it's defined within a function
> call it only has context within that function and the value will not be
> carried outside of it.

It works to define it in the first two lines of the script:
const
Remove_Headers='User-Agent: ,Message-ID: ';
// Remove_Headers='User-Agent: ,Content-Transfer-Encoding: ';
// Remove_Headers='User-Agent: ,Mime-Version: ';

That works just fine.
Of course, I manually have to uncomment whichever Remove_Header variable I
want to use to post with. But that works fine.

The only thing I'm trying to add is to automatically re-define the
Remove_Header based on the id1 or id2.

I must have the definition syntax wrong because it won't work whenever I
define Remove_Headers for a second time.

That's really, I think, my syntax block of stumbling.

Stijn De Jong

unread,
Dec 31, 2016, 4:28:24 PM12/31/16
to
Op Sat, 31 Dec 2016 20:43:21 +0000 (GMT), Rodney Pont schreef:

> I can't tell you exactly what to do since I can't follow the code, I've
> got CFS/ME and my short term memory isn't any good, I can follow a few
> lines but no more, the earlier lines have just left me.

I understand and you've given me more help than I deserve since I really
don't understand how to just redefine the variable "Remove_Headers".

Redefining a variable should be just about the simplest thing anyone can
do, so, the fact I can't do that is my major problem stumbling.

To give back and pay forward any help, and in case you, or anyone want to
install Dialog and test the scripts yourself, here is how you can do that.

1. Install version 2.0.15.1 from the "4d2b38.exe" installer.
(for our purposes, this version works fine)
(if you like, you can update to 2.0.15.41 Beta 38)
(but do not upgrade to 40tude Dialog Alpha .84)
2. Set up your news servers:
Dialog: Settings > Servers,Identities,Signatures > Newsservers > New
(for example: nntp.aioe.net 119)
3. Set up your identity:
Dialog: Settings > Servers,Identities,Signatures > Identities > New
(for example: FirstName LastName Emaila...@domain.com)
4. OPTIONAL: Subscribe and read and post to your desired newsgroups:
a. Click on the "All" tab
b. Put your cursor on the top newsgroup before searching!
c. Type "control+f" to bring up the find menu
d. Type the name of the desired newsgroup.
e. Select the newsgroup & right click & select "subscribe"

Once you get the hang of using Dialog as a Usenet client, then you can add
a script (any script will do).
1. Obtain the remove headers script:
http://dialog.datalist.org/scripts/RemoveHeaders.html
2. Obtain the check identity script:
http://dialog.datalist.org/scripts/CheckingIdentity.html
3. Load either one of those two scripts into 40Tude Dialog:
Dialog: Settings > Scripting > Scripting > Event Scripts >
OnBeforeSendingMessage > (copy & paste script here)
4. Compile the script to check for errors:
Scripting: Script > Compile (look for "Successfully compiled")
5. Save the compiled script (it will force you to save anyway):
Scripting: File > Save

At this point anyone would see exactly what I see.

Stijn De Jong

unread,
Dec 31, 2016, 4:35:16 PM12/31/16
to
Op Sat, 31 Dec 2016 22:28:15 +0100, Stijn De Jong schreef:

> To give back and pay forward any help, and in case you, or anyone want to
> install Dialog and test the scripts yourself, here is how you can do that.

I realized a line was missing so I repeat with the URL for the installer!

To give back and pay forward any help, and in case you, or anyone want to
install Dialog and test the scripts yourself, here is how you can do that.

1. Install from http://dialog.datalist.org/downloads/download.html
(for our purposes version 2.0.15.1 works fine)
(if you like, you can update to 2.0.15.41 Beta 38)
(but do not upgrade to 40tude Dialog Alpha .84)

The update to 2.0.15.41 is purely optional but here is the process:
a. First install 40tude Dialog 2.0.15.1 from the exe installer.
b. Rename C:\Program Files\40tude Dialog\dialog.exe to anything else.
c. Extract the v41 "dialog.exe" to replace the original dialog.exe file.
d. Check versions: 40TudeDialog: Help > About
If you do this update, you'll see: Version 2.0.15.41 (Beta 38

Rodney Pont

unread,
Dec 31, 2016, 4:40:26 PM12/31/16
to
On Sat, 31 Dec 2016 21:45:08 +0100, Stijn De Jong wrote:

>This is the same as above, but with the Remove_Header inserted:
>https://i.imgsafe.org/8182381b0a.jpg
>
>function From2Identity(from: String): String;
var
Remove_Headers : String;

>begin
> if (StrMatch(from, 'Stijn De Jong <stijnd...@nlnet.nl>')) then
> result := 'id1'
> Remove_Headers := 'User-Agent: ,Message-ID: ';
> else if (StrMatch(from, 'First1 Last2 <ema...@domain.com>')) then
> result := 'id2'
> Remove_Headers := 'User-Agent: ,Content-Transfer-Encoding: ';
> else
> result := 'unknown';
> Remove_Headers := 'User-Agent: ,Mime-Version: ';
>end;

Try adding the var section as above. If that says it's a duplicate the
Remove_Headers has been defined elsewhere, likely as a const, so try to
find where and change it to a string.

VanguardLH

unread,
Dec 31, 2016, 5:11:34 PM12/31/16
to
Okay, I'll bite. Why do you have to remove Dialog's own generated
Message-ID header that you told it to add instead of just configuring
Dialog to not add the header in the first place (and have the server add
its own MID header)? I do NOT have Dialog add a MID header. I let the
server add the MID header. According to NNTP RFCs, the server will add
the MID header *if* the client did not already add one. I would prefer
servers discard any client-added MID header and always add the server's
own MID header but the RFCs say the client can do it. If you configure
Dialog to NOT add a MID header then there isn't one to remove.

Sorry, I've not bothered to lie about what NNTP client that I use or
keep it a secrete so I don't know how to configure Dialog to not add a
UA header. While I know you can use a macro (script) to iterate through
a received message to parse and modify it (which is how I get rid of
those worthless PGP "sigs" in the body of a message), I don't that you
could do the same line-by-line iteration through a document that has not
yet been sent by Dialog.

For more detailed info about how to write macros on events in Dialog,
and since you cross-posted to the news.software.readers newsgroup, you
might want to wait until Bernd Rose shows up. He knows the inner
workings of Dialog and better understands the internal structures and
variables known and used by Dialog. There is no documentation on the
environment in which the macros will run so too often a user has no clue
on how to code the script (which becomes a fragment in the main
program). If he doesn't respond, you might want to start a new thread,
like "Ping Bernd Rose - <topic>". Hopefully he still visits the
news.software.readers newsgroup.

For scripting in Dialog, you use ":=" to assign/test a value to/of a
variable, not "=". You should not attempt to "redefine that variable"
in an if-statement. While it is doable, like in C, it means you are
trying to alter the value on which you intent to test its value. In a
for-statement, yes, you do want to change the variable's value on each
iteration of the for-loop but you do not change its value when testing
the current value of the variable.

Sorry, but to me it looks like you are trying to avoid recognitions of
your nyshifting and your socks by making your header vary when using
different identities in Dialog. There's no reason to change all those
headers between different identities other than to alter your
fingerprint for each of your sock puppets.

Stijn De Jong

unread,
Dec 31, 2016, 5:46:50 PM12/31/16
to
Op Sat, 31 Dec 2016 16:11:33 -0600, VanguardLH schreef:

> Okay, I'll bite. Why do you have to remove Dialog's own generated
> Message-ID header that you told it to add instead of just configuring
> Dialog to not add the header in the first place (and have the server add
> its own MID header)?

Your question makes complete sense since you didn't realize that those were
just simplified strings for the variable "Remove_Headers".

So it's my fault for saying that the value of the Remove_Headers will
change depending on the need - but the value of the Remove_Headers never
was the question.

So I just put arbitrary values for Remove_Header in the post because the
actual value of the "Remove_Headers" variable is not in the least relevant
to the stated problem.

But the fact you asked the question shows you are both thinking, and you
know that 40Tude allows the user to turn off dialog=-generated message ids,
so I appreciate your acumen.

> I do NOT have Dialog add a MID header. I let the
> server add the MID header.

I completely undersstand.
You can have the server set the date also.

These are dialog-related facts which are completely outside the problem set
though, which is that I'm having trouble with the syntax of setting the
Remove_Headers variable depending on the id of the outgoing sender.

> If you configure
> Dialog to NOT add a MID header then there isn't one to remove.
Yup. But that doesn't change the problem set in the least.
:)

> Sorry, I've not bothered to lie about what NNTP client that I use or
> keep it a secrete so I don't know how to configure Dialog to not add a
> UA header.

It's super easy to do that!

1. Load this script:
http://dialog.datalist.org/scripts/RemoveHeaders.html
2. Set this variable:
Remove_Headers='User-Agent: ';
3. Voila!
No user-agent header.

The problem never was removing the headers.
Nor was the problem figuring out who the sending id is:

The problem is the syntax for melding those two scripts together so that
the script can choose which headers to remove based on the sending id.

Specifically, I can't seem to set the Remove_Header to one thing in one
part of the script, and then change it to another thing in the line just
below the first.

That's weird.

We should be able to do something like this:
variable = 1
echo $variable <===== this should output "1"
variable = 2
echo $variable <===== this should output "2"

For whatever syntax reason, I can't re-define the "Remove_Headers".


> For more detailed info about how to write macros on events in Dialog,
> and since you cross-posted to the news.software.readers newsgroup, you
> might want to wait until Bernd Rose shows up. He knows the inner
> workings of Dialog and better understands the internal structures and
> variables known and used by Dialog.

OK. I've had this problem for months, so I can wait for Bernd Rose to show
up.

> For scripting in Dialog, you use ":=" to assign/test a value to/of a
> variable, not "=". You should not attempt to "redefine that variable"
> in an if-statement. While it is doable, like in C, it means you are
> trying to alter the value on which you intent to test its value. In a
> for-statement, yes, you do want to change the variable's value on each
> iteration of the for-loop but you do not change its value when testing
> the current value of the variable.

My main stumbling problem is why can't I just do this?

Remove_Headers='whatever';
Remove_Headers='something else';

Stijn De Jong

unread,
Dec 31, 2016, 6:19:00 PM12/31/16
to
Op Sat, 31 Dec 2016 21:35:45 +0000 (GMT), Rodney Pont schreef:

> var
> Remove_Headers : String;
> Try adding the var section as above. If that says it's a duplicate the
> Remove_Headers has been defined elsewhere, likely as a const, so try to
> find where and change it to a string.

I see what you're getting at, which is to define the string as a variable
instead of as a constant.

Given that syntax is my only problem, this definition should work as the
first 2 lines of the program after the "program" line, right?

program OnBeforeSendingMessage;
var
Remove_Headers : 'User-Agent: ,Date: ';

Unfortunately, that fails with the error below:
http://i.imgsafe.org/8398770bfe.jpg
"(Error) OnBeforeSendingMessage.ds(3.18): Identifier expected

The actual syntax goal would be solved if I can do this:
program OnBeforeSendingMessage;
var
Remove_Headers : 'User-Agent: ,Date: ';
Remove_Headers : 'User-Agent: ';
Remove_Headers : 'Date: ';

function OnBeforeSendingMessage():boolean;
begin
end;

begin
end.

I tried exactly that above, which is as simple as I can make the program.

It failed with the same error:
http://i.imgsafe.org/83b4808676.jpg

The simple script fails with a "duplicate identifier":
http://i.imgsafe.org/83c1060a72.jpg

program OnBeforeSendingMessage;
const
Remove_Headers = 'User-Agent: ,Date: ';
Remove_Headers = 'User-Agent: ';
Remove_Headers = 'Date: ';

function OnBeforeSendingMessage():boolean;
begin
end;

begin
end.

Rodney Pont

unread,
Jan 1, 2017, 3:15:27 AM1/1/17
to
On Sun, 1 Jan 2017 00:18:50 +0100, Stijn De Jong wrote:

>Op Sat, 31 Dec 2016 21:35:45 +0000 (GMT), Rodney Pont schreef:
>
>> var
>> Remove_Headers : String;
>> Try adding the var section as above. If that says it's a duplicate the
>> Remove_Headers has been defined elsewhere, likely as a const, so try to
>> find where and change it to a string.
>
>I see what you're getting at, which is to define the string as a variable
>instead of as a constant.
>
>Given that syntax is my only problem, this definition should work as the
>first 2 lines of the program after the "program" line, right?
>
>program OnBeforeSendingMessage;
>var
>Remove_Headers : 'User-Agent: ,Date: ';

No, that shouldn't work, the var section should be used to define
variables, not to set them to a value, it needs the word String to tell
it that the variable is a string type, see above.

>Unfortunately, that fails with the error below:
>http://i.imgsafe.org/8398770bfe.jpg
>"(Error) OnBeforeSendingMessage.ds(3.18): Identifier expected
>
>The actual syntax goal would be solved if I can do this:
>program OnBeforeSendingMessage;
>var
> Remove_Headers : 'User-Agent: ,Date: ';
> Remove_Headers : 'User-Agent: ';
> Remove_Headers : 'Date: ';

Even once you have defined the variable as a string it will only hold
one assignment at a time so each time you assign a new value it
overwrite the previous one and will have the value 'Date: '.

I think you need to have the var section to define the string variable
then you need you if elses to set it's value.

>function OnBeforeSendingMessage():boolean;
>begin
>end;
>
>begin
>end.
>
>I tried exactly that above, which is as simple as I can make the program.
>
>It failed with the same error:
>http://i.imgsafe.org/83b4808676.jpg
>
>The simple script fails with a "duplicate identifier":
>http://i.imgsafe.org/83c1060a72.jpg
>
>program OnBeforeSendingMessage;
> const
> Remove_Headers = 'User-Agent: ,Date: ';
> Remove_Headers = 'User-Agent: ';
> Remove_Headers = 'Date: ';
>
>function OnBeforeSendingMessage():boolean;
>begin
>end;
>
>begin
>end.

Stijn De Jong

unread,
Jan 1, 2017, 6:13:33 AM1/1/17
to
Op Sun, 01 Jan 2017 08:11:09 +0000 (GMT), Rodney Pont schreef:

>>program OnBeforeSendingMessage;
>>var
>>Remove_Headers : 'User-Agent: ,Date: ';
>
> No, that shouldn't work, the var section should be used to define
> variables, not to set them to a value, it needs the word String to tell
> it that the variable is a string type, see above.

HAPPY NEW YEAR!

My mistake. I thought you were writing pseudocode.

I just tried your method, and, I was shocked.
It was the first time I did NOT get an error!
http://i.imgsafe.org/8e26e05534.jpg
(Sorry for doubting you.) :)

So this "variable" thing is where I'll head next to try to resolve the
problem.

Unfortunately, it still failed when I tried to define the string. :(
http://i.imgsafe.org/8e27315499.jpg

program OnBeforeSendingMessage;
var
Remove_Headers : String;

Remove_Headers='User-Agent: ,Date: ';
Remove_Headers='User-Agent: ';
Remove_Headers='Date: ';

Note that I'm just testing by redefining the string three times.
If it's a variable, that should not cause any error.

Later on, once I can redefine the string, I will put it in an ifthenelse
statement, but if I can't redefine it, the ifthenelse won't work either.

>>Unfortunately, that fails with the error below:
>>http://i.imgsafe.org/8398770bfe.jpg
>>"(Error) OnBeforeSendingMessage.ds(3.18): Identifier expected
>>
>>The actual syntax goal would be solved if I can do this:
>>program OnBeforeSendingMessage;
>>var
>> Remove_Headers : 'User-Agent: ,Date: ';
>> Remove_Headers : 'User-Agent: ';
>> Remove_Headers : 'Date: ';
>
> Even once you have defined the variable as a string it will only hold
> one assignment at a time so each time you assign a new value it
> overwrite the previous one and will have the value 'Date: '.

This is what I want since I'm only trying to simplify the test case.
If it's a variable, it should be able to take on any value, right?

> I think you need to have the var section to define the string variable
> then you need you if elses to set it's value.

Since I was taking this step by step, where I first try to change the value
and then once I can change the value, I can put it in an ifthenelse
construct, I have to ask this question.

Why can't I just set its value, for test purposes, to anything I want, and
then change its value?

var
Remove_Headers : String;
Remove_Headers='foo';
Remove_Headers='bar';

That seems to be the critical syntactical problem that I think I need to
resolve, otherwise the iftehnelse will have the same problem anyway.

HAPPY NEW YEAR!

Rodney Pont

unread,
Jan 1, 2017, 11:00:27 AM1/1/17
to
On Sun, 1 Jan 2017 12:13:16 +0100, Stijn De Jong wrote:

>Why can't I just set its value, for test purposes, to anything I want, and
>then change its value?
>
>var
>Remove_Headers : String;
>Remove_Headers='foo';
>Remove_Headers='bar';
>
>That seems to be the critical syntactical problem that I think I need to
>resolve, otherwise the iftehnelse will have the same problem anyway.

Try, I think assignment needs the := syntax:
Remove_Headers:='foo';
Remove_Headers:='bar';

>HAPPY NEW YEAR!
Happy new year to you too.

Stijn De Jong

unread,
Jan 1, 2017, 12:52:26 PM1/1/17
to
Op Sun, 01 Jan 2017 15:47:11 +0000 (GMT), Rodney Pont schreef:

> Try, I think assignment needs the := syntax:
> Remove_Headers:='foo';
> Remove_Headers:='bar';

The syntax for dialog scripts is utterly incomprehensible.
I had already tried a half-dozen (hit or miss) attempts and all failed.

http://i.imgsafe.org/94013af980.jpg

program OnBeforeSendingMessage;
var
Remove_Headers : String;
Remove_Headers:='foo';
Remove_Headers:='bar';
const
RemoveFromEmails = true;
RemoveFromNews = true;
procedure RemoveHeaders ( Message : TStringlist;
IsEmail : boolean
);

Failed when compiling
[Error] OnBeforeSendingMessage.ds(4:1): Duplicate identifier
'Remove_Headers'

I think I'm going to give up because I don't want to run you ragged.

It seems, for now, that it's impossible to define a variable and change it
in 40Tude Dialog, unless n unknown but very specific Dialog syntax is used.

Rodney Pont

unread,
Jan 1, 2017, 4:00:26 PM1/1/17
to
On Sun, 1 Jan 2017 18:52:09 +0100, Stijn De Jong wrote:

>http://i.imgsafe.org/94013af980.jpg
>

Try:

program OnBeforeSendingMessage;
var
Rmv_Hdrs : String;


Rmv_Hdrs:='foo';
Rmv_Hdrs:='bar';
>const
> RemoveFromEmails = true;
> RemoveFromNews = true;
>procedure RemoveHeaders ( Message : TStringlist;
> IsEmail : boolean
>);
>

Then change Remove_Headers to Rmv_Hdrs in the RemoveHeaders procedure
at line 19 in the jpg you linked to above.

>Failed when compiling
>[Error] OnBeforeSendingMessage.ds(4:1): Duplicate identifier
>'Remove_Headers'
>
>I think I'm going to give up because I don't want to run you ragged.
>
>It seems, for now, that it's impossible to define a variable and change it
>in 40Tude Dialog, unless n unknown but very specific Dialog syntax is used.

I suspect the problem is because Remove_Headers is being defined
elsewhere, I doubt if the problem is with the assignment. That's why
I've suggested using a different variable name.

Do they have a forum or somewhere you can ask?

Mike Easter

unread,
Jan 1, 2017, 4:32:24 PM1/1/17
to
Rodney Pont wrote:
> Do they have a forum or somewhere you can ask?

The site with the script library recommends:

"Support for Dialog and Dialog scripting can usually be found on the
"news.software.readers" Usenet group. Begin the subject line of your
post with "[Dialog]" for the best response."

Library: http://dialog.datalist.org/scripts/script_library.html


--
Mike Easter

Stijn De Jong

unread,
Jan 2, 2017, 9:17:13 AM1/2/17
to
Op Sun, 1 Jan 2017 13:32:20 -0800, Mike Easter schreef:

> "Support for Dialog and Dialog scripting can usually be found on the
> "news.software.readers" Usenet group. Begin the subject line of your
> post with "[Dialog]" for the best response."
>
> Library: http://dialog.datalist.org/scripts/script_library.html

I didn't see this until now, but here is the current script, which no
longer has syntax errors and it re-defines the Remove_Headers variable.

It doesn't actually do anything though, so, the logic must be wrong.

I think the problem is that the if-then-else that decides whether to use
the personal or business headers isn't getting or putting back the
re-defined variable (because its not showing up in the log file).

Here's the current syntax-correct but logic-incorrect script which is
simply these two scripts melded together:
1. Determine Identity (either work or personal):
http://dialog.datalist.org/scripts/CheckingIdentity.html
2. Remove Headers:
http://dialog.datalist.org/scripts/RemoveHeaders.html

The goal was simply to meld the two above so that the headers change
depending on the identity (either work or personal).
--------------- cut here -------------
// The goal is different headers for work use versus for personal use.
// This script has no syntax errors.
// Modify the following values to fit your setup
// 1. Remove_Headers (one for work and one for personal)
// 2. Identity (one for work and one for personal)
// 3. Newsgroups (work newsgroups can be different than personal ones)
// 4. Servers (work servers can be different than personal servers)
//
program OnBeforeSendingMessage;

var Remove_Headers:string;
Begin
// These are just default values.
// The real values are set in an if-then-else statement later.
Remove_Headers := 'X-Scoring: ,X-Hamster-Info: ';
Remove_Headers := 'X-Scoring: ';
WriteLn(Remove_Headers);
End.
RemoveFromEmails = true;
RemoveFromNews = true;
procedure RemoveHeaders ( Message : TStringlist;
IsEmail : boolean
);
function From2Identity(var Remove_Headers TStringlist; from: String;):
String;
begin
if (StrMatch(from, 'First1 Last1 <ema...@example.com>')) then
result := 'id1'
Remove_Headers='User-Agent: ,Message-ID: '
else if (StrMatch(from, 'First2 Last2 <ema...@example.com>')) then
result := 'id2'
Remove_Headers='Message-ID: ,Mime-Version: '
else
result := 'unknow';
WriteLn(Remove_Headers);
end;

function NewsGroup2Identity(newsgroup: String): String;
begin
if (StrMatch(newsgroup, 'news.software.readers') or
StrMatch(newsgroup, 'alt.os.linux')) then
result := 'id1'
else
result := 'id2';
end;
// The server identity doesn't seem to play any role in the decisions
though...
function Server2Identity(server: String): String;
begin
if (CompareStr(server, 'aioe_119') = 0) then
result := 'id1'
else
WriteToLog(' fromIdentity = ' + fromIdentity, 7);
WriteToLog(' newsgroupIdentity = ' + newsgroupIdentity, 7);
WriteToLog(' serverIdentity = ' + serverIdentity, 7);
WriteToLog(' Remove_Headers = ' + Remove_Headers,7);
if ((CompareStr(fromIdentity, newsgroupIdentity) = 0) and
(CompareStr(newsgroupIdentity, serverIdentity) = 0)) then
result := true
else
result := BadIdentity();
end
else
result := true;
end;

function OnBeforeSendingMessage(var Message : TStringlist;
Servername : string;
IsEmail : boolean
):boolean;
begin
// Added the result line below:
RemoveHeaders(Message,IsEmail);
WriteLn(Remove_Headers);
result := CheckIdentity(message, servername, isEmail);
result:=true;
end;
// ----------------------------------------------------------------------
begin
end.
--------------- cut here -------------

Stijn De Jong

unread,
Jan 2, 2017, 9:28:51 AM1/2/17
to
Op Sun, 01 Jan 2017 20:45:40 +0000 (GMT), Rodney Pont schreef:

> Try:
> program OnBeforeSendingMessage;
> var
> Rmv_Hdrs : String;
> Rmv_Hdrs:='foo';
> Rmv_Hdrs:='bar';
> Then change Remove_Headers to Rmv_Hdrs in the RemoveHeaders procedure
> at line 19 in the jpg you linked to above.
> http://i.imgsafe.org/94013af980.jpg

Thanks Rodney for the added help, as I'm close to giving up since I should
have known that it's too difficult for a layperson like me to logically
figure out a scripting language.

I did, however, with help from an expert on the language, get past the
stumbler of the syntax, which is that a "begin" statement had to be used to
re-assign the variable.

http://i.imgsafe.org/99dc6c0dbe.jpg

Program setRemoveHeadersString;
var Remove_Headers:string;
Begin
Remove_Headers := 'X-Scoring: ,X-Hamster-Info: ';
Remove_Headers := 'X-Scoring: ';
WriteLn(Remove_Headers);
End.

I posted separately the current version, which has no syntax errors, but
which fails to do anything (not even what they did originally), where all I
essentially did was try to insert the Remove_Headers definition into an
if-then-else condition.

The script would be generally useful to those who have different
requirements for work versus for personal use of the Usenet, so my
dissillusionment will do others a dissservice.

I may try to tackle it again in the future, but I think I'm out of my
league because I can't get the if-then-else to use the re-defined variable
(or even spit it out to the log file).

Rodney Pont

unread,
Jan 2, 2017, 11:00:26 AM1/2/17
to
On Mon, 2 Jan 2017 15:28:29 +0100, Stijn De Jong wrote:

>Thanks Rodney for the added help, as I'm close to giving up since I should
>have known that it's too difficult for a layperson like me to logically
>figure out a scripting language.

I think you were just taking on a bit too difficult a task for your
experience. After all you did get to grips with the idea of if, then
else :-)

Good luck if you do come back to it.

Stijn De Jong

unread,
Jan 2, 2017, 1:23:10 PM1/2/17
to
Op Mon, 02 Jan 2017 15:54:15 +0000 (GMT), Rodney Pont schreef:

> I think you were just taking on a bit too difficult a task for your
> experience. After all you did get to grips with the idea of if, then
> else :-)

Thanks for the kind words. I thought, at first, it would be easier to
decipher what the program did, since a program is written, essentially, in
intuitively syntactic english.

However, the tyranny of the specific syntax vagaries defied intuition.

I still (wrongly) thought that I could experiment my way through the
syntactic vagaries, but they defied all intuitive logic.

You simply had to know that a BEGIN statement was required to change the
value of a variable. This is not in the least intuitive, and never will be.

> Good luck if you do come back to it.

I think the two problems that still stumble me are:
1. How do I pass the variable into and out of the procedure that contains
the ifthenelse (because I think that's not working).

2. How do I call, in the final lines, the two procedures so that they work
together.

If/when I can figure that out, everyone with a work/personal account who
uses different servers, newsgroups, or headers, will be able to use it (if
they use dialog).

Bernd Rose

unread,
Jan 2, 2017, 1:50:05 PM1/2/17
to
On Mon, 2nd Jan 2017 19:22:47 +0100, Stijn De Jong wrote:

> You simply had to know that a BEGIN statement was required to change the
> value of a variable.

Wrong. You mis-interpreted what I wrote. You need to differentiate between
the declaration section and the program-code section of a program. (Or of
embedded procedures or functions, for that matter...) Starting to write
programs or scripts without knowledge of the programming language and a
good reference is never a good idea. So have a look at the help file and
the (online) reference book recommended by Marcus Mönnig, the author of
Dialog. - See my other post:

Message-ID: <w4daz9t9jqbr$.d...@b.rose.tmpbox.news.arcor.de>

Bernd

Ken Blake

unread,
Jan 2, 2017, 2:10:36 PM1/2/17
to
On Mon, 2 Jan 2017 19:22:47 +0100, Stijn De Jong
<stijnd...@nlnet.nl> wrote:

>I thought, at first, it would be easier to
>decipher what the program did, since a program is written, essentially, in
>intuitively syntactic english.


How intuitive a program is depends on what language it is written in.
Some are very intuitive; other are not at all intuitive.

Mike Easter

unread,
Jan 2, 2017, 3:49:21 PM1/2/17
to
Ken Blake wrote:
> How intuitive a program is depends on what language it is written in.
> Some are very intuitive; other are not at all intuitive.

The developer has provided a wealth of scripts. One good way to learn
how a language works is to read a lot of scripts provided by an expert
in the language, which are available.

--
Mike Easter

JJ

unread,
Jan 3, 2017, 11:07:15 AM1/3/17
to
On Sat, 31 Dec 2016 21:01:15 +0100, Stijn De Jong wrote:
> Op Sat, 31 Dec 2016 20:50:46 +0100, Stijn De Jong schreef:
>
>> This is the code I am using which sets the identity.
>> http://dialog.datalist.org/scripts/CheckingIdentity.html
>>
>> This is the code I am using which removes the headers:
>> http://dialog.datalist.org/scripts/RemoveHeaders.html
>>
>> All I'm trying to do is meld the two, where the outgoing headers to be
>> removed depend on the identity of the sender.
>
> At the risk of confusing the issue, here is the current code that was used
> to send this message, which has no syntax errors, and which sort of works
> but which allows only a single static setting for the remove headers
> variable.
>
> All I'm trying to do is add the simple decision below:
[snip]

Please use below modified script.

<http://pastebin.com/9kBWDbU8>

I've added some comments for reference. HTH.

Stijn De Jong

unread,
Jan 3, 2017, 4:31:32 PM1/3/17
to
Op Tue, 3 Jan 2017 23:07:15 +0700, JJ schreef:

> Please use below modified script.
>
> <http://pastebin.com/9kBWDbU8>
>
> I've added some comments for reference.

test...

Stijn De Jong

unread,
Jan 4, 2017, 4:56:52 PM1/4/17
to
Op Tue, 3 Jan 2017 22:31:24 +0100, Stijn De Jong schreef:

>> Please use below modified script.
>>
>> <http://pastebin.com/9kBWDbU8>
>>
>> I've added some comments for reference.
>
> test...

Thank you for that modified script, where I see that you left everything as
it was and changed the part that needed to be changed, which was the way
that the headers were defined for business versus for personal posts and
emails.

Your script has no syntax errors and therefore I've been testing it but I
haven't gotten it to actually work yet (which is why I haven't reported
back until now because I was hoping to report a success).

The great thing is that the decision to have personal or business headers
seems to be syntactically safe inside an ifthenelse.

But the bad news (so far) is that it doesn't do what it's supposed to do.

However, the original question was about the syntax for setting the header
variable so now the problem is mine because it's about the program flow.

Since the hope is that others can also use this program, I do suggest that
anyone using the wonderful program you provided add something like the
following to the header comments.

// Source code: "http://pastebin.com/9kBWDbU8"
// From: JJ <jj4p...@vfemail.net>
// Newsgroups: news.software.readers,alt.windows7.general
// Subject: Re: Request help with 40tude dialog program syntax
// Date: Tue, 3 Jan 2017 23:07:15 +0700
// Message-ID: <1ibo1gzmbqy5b.3...@40tude.net>
// ACTION:
// 1. Change identity as needed (search for "from,")
// 2. Change newsgroup as needed (search for "newsgroup,")
// 3. Change server as needed (search for "server,")
// 4. Change header as needed (search for "Remove_Headers :"

JJ

unread,
Jan 5, 2017, 11:06:19 AM1/5/17
to
Sorry. There was an error in the previous script. Please use this one. This
time, I've tested it thoroughly. :)

<http://pastebin.com/2tMYRKM4>

I've changed it to include the ability to add new headers, and made it so
that any identity may be empty. It'll be up to the main decision code to
check each identity. Note that the string format for `Add_Headers` is
different from `Remove_Headers` (see `AddHeader()` function comments and the
example in the main decision code).

I've also added to more variables `ForEmail` and `ForNewsgroup` to indicate
which type of message should be processed so that it's more flexible. Both
can be `true` to add/remove headers on both message types. But both must not
be `false`, otherwise nothing will be processed. The `RemoveHeaders()`
function was changed for this purpose.

Since headers removal is performed first, then the headers insertion, you
can use both `Remove_Headers` and `Add_Headers` to change any existing
header. i.e. add if not exist, or change it if one exist. e.g.

Remove_Headers:= 'User-Agent: ';
Add_Headers:= 'User-Agent: Thunderbird 2086 (Windows 3000; NT9.0)'#13#10;

Stijn De Jong

unread,
Jan 5, 2017, 6:42:55 PM1/5/17
to
> Sorry. There was an error in the previous script. Please use this one. This
> time, I've tested it thoroughly. :)
>
> <http://pastebin.com/2tMYRKM4>

Thanks for sticking with us, as I think it would be generally useful to
others also to have a different set of headers and cross checks based on
personal versus work posts and emails (for example to be able to avoid
posting to work newsgroups using the personal login and vice versa, to
avoid using business servers for personal posts).

As soon as I saw your post, I picked up: http://pastebin.com/raw/2tMYRKM4
and saved it to disk using control+a control+c so that all the syntax is
preserved and I added the following comments in the header.

// JJ_add_and_remove_headers_while_doublechecking_identity_ng_and_servers
// <http://pastebin.com/2tMYRKM4>
// From: JJ <jj4p...@vfemail.net>
// Newsgroups: news.software.readers,alt.windows7.general
// Subject: Re: Request help with 40tude dialog program syntax
// Date: Thu, 5 Jan 2017 23:06:19 +0700
// Message-ID: <7vpx5y09pu98.1sukl5d600sda$.d...@40tude.net>
// Original code for checking identity:
// http://dialog.datalist.org/scripts/CheckingIdentity.html
// Original code for modifying headers:
// http://dialog.datalist.org/scripts/RemoveHeaders.html
// ACTION:
// 1. Change identity as needed (search for "from,")
// 2. Change newsgroup as needed (search for "newsgroup,")
// 3. Change server as needed (search for "server,")
// 4. Change remove header as needed (search for "Remove_Headers :")
// 5. Change add header as needed (search for "Add_Headers :")

The only thing I changed was that I added the syntax to add an "or"
condition to the string match of the newsgroup lines (so that people have a
ready-made template for changing the list of newsgroups syntactically):

FROM:
if StrMatch(newsgroup, 'news.software.readers') then
result := 'id1'
TO:
if StrMatch(newsgroup, 'news.software.readers') or
StrMatch(newsgroup, 'alt.windows7.general') then
result := 'id1'

> I've changed it to include the ability to add new headers,

I was always planning on doing that so you think similarly to the way I
think, which is that personal and business headers can not only be removed,
but added. I just didn't know how to do that so I didn't ask that question.

Thanks for adding that capability to add headers as needed (which I'll test
out subsequently).

> and made it so that any identity may be empty.

I'm not sure what that means that any identity may be empty, but I think
what you mean is that the default should be that you shouldn't have to set
the identity and if you don't set the identity, then the settings will work
for all identities (which is, in effect, how the remove_headers original
program worked).

> Note that the string format for `Add_Headers` is
> different from `Remove_Headers` (see `AddHeader()` function comments and the
> example in the main decision code).

Thank you for pointing out that the syntax for adding headers is different
than the syntax for removing headers.

> I've also added to more variables `ForEmail` and `ForNewsgroup` to indicate
> which type of message should be processed so that it's more flexible. Both
> can be `true` to add/remove headers on both message types. But both must not
> be `false`, otherwise nothing will be processed. The `RemoveHeaders()`
> function was changed for this purpose.

Thank you for fixing the for-mail and for-news variables, which I think,
were each done differently in the two original programs that comprise the
bulk of this program.

> Since headers removal is performed first, then the headers insertion, you
> can use both `Remove_Headers` and `Add_Headers` to change any existing
> header. i.e. add if not exist, or change it if one exist. e.g.
>
> Remove_Headers:= 'User-Agent: ';
> Add_Headers:= 'User-Agent: Thunderbird 2086 (Windows 3000; NT9.0)'#13#10;

That's a nice program-flow consideration!

You can remove a header and then add a different header in its place.
I will test this out and let you know how it works.

Stijn De Jong

unread,
Jan 5, 2017, 7:00:01 PM1/5/17
to
> X-Comment: If this shows up, JJ is a veritable genius!

That Add_Header line worked!

> FROM:
> if StrMatch(newsgroup, 'news.software.readers') then
> result := 'id1'
> TO:
> if StrMatch(newsgroup, 'news.software.readers') or
> StrMatch(newsgroup, 'alt.windows7.general') then
> result := 'id1'

But this had some kind of syntax error so I had to put it back to your
original single newsgroup. But to help others with syntax, I need to
experiment to see how to fix that so there is at least one example that can
handle multiple newsgroups.

if (StrMatch(newsgroup, 'ng1') or StrMatch(newsgroup, 'ng2'))

Here's a vignette of what I'm using for this post:

function NewsGroup2Identity(newsgroup: String): String;
// id1 is for news.software.readers,alt.windows7.general
//SYNTAX: if (StrMatch(newsgroup, 'ng1') or StrMatch(newsgroup, 'ng2'))
//
begin
if (StrMatch (newsgroup, 'news.software.readers')
or StrMatch(newsgroup, 'alt.windows7.general')) then
result := 'id1'
else if StrMatch(newsgroup, 'alt.free.newsservers') then
result := 'id2'
else if StrMatch(newsgroup, 'alt.test') then
result := 'id3'
else
result := '';
end;

Stijn De Jong

unread,
Jan 5, 2017, 7:41:06 PM1/5/17
to
On Fri, 6 Jan 2017 00:59:55 +0100, you wrote:

> But this had some kind of syntax error

The script compiles, executes, and saves without error.

The only error I'm getting is Dialog is complaining when I actually send
the message.

Then I get the following error:

Posting article failed: 437 Space before colon in "On Fri, 6 Jan 2017"
header;

I think it may be related to the add header where you warned me to add the
CR+LF (aka #13#10) but I didn't initially heed that warning.

If you get this, then adding the pount13-pound10 CR+LF worked.

if FromIdentity = 'id1' then
begin
ForNewsgroup := true;
Remove_Headers := 'User-Agent: ,Message-ID: ';
Add_Headers := 'X-Comment: JJ is a veritable genius!'#13#10;
end

Stijn De Jong

unread,
Jan 5, 2017, 8:03:54 PM1/5/17
to
On Fri, 6 Jan 2017 00:41:03 +0000 (UTC), you wrote:

> If you get this, then adding the pount13-pound10 CR+LF worked.

I should never have doubted you JJ!

The moment I added back the pound13-pound10, I no longer received that
error from Dialog upon sending of "437 space before colon".

So that others can get the benefit of JJ's efforts and my added comments,
here is the script I just used which worked perfectly:
http://pastebin.com/7n6SvGuh

The overall goal is to keep personal and business news and/or email
separate simply by setting appropriate variables in the script below.

Here is that same script pasted into this post, but it might get modified
by newsreaders so the pastebin raw source is probably more reliable.

All the thanks go to the original authors, and JJ and those who helped in
between!

This script below is essentially the same as the one you just posted, but
with a few more comments and a couple more examples involved (but otherwise
the same).

// JJAddAndRemoveHeadersWhileDoubleCheckingIdentityNgAndServers
// <http://pastebin.com/2tMYRKM4>
// More comments & examples: http://pastebin.com/7n6SvGuh
// From: JJ <jj4p...@vfemail.net>
// Newsgroups: news.software.readers,alt.windows7.general
// Subject: Re: Request help with 40tude dialog program syntax
// Date: Thu, 5 Jan 2017 23:06:19 +0700
// Message-ID: <7vpx5y09pu98.1sukl5d600sda$.d...@40tude.net>
// Original code for checking identity:
// http://dialog.datalist.org/scripts/CheckingIdentity.html
// Original code for modifying headers:
// http://dialog.datalist.org/scripts/RemoveHeaders.html
// CUSTOMIZATION:
// 1. Set the "ForEmail" Boolean as desired (search for "ForEmail :")
// 2. Set the "ForNewsgroup" Boolean as desired (search for "ForNewsgroup
:")
// 3. Change identity as desired (search for "from,")
// 4. If ForNewsgroup is true, change newsgroup as desired (search for
"newsgroup,")
// 5. Change server as desired (search for "server,")
// 6. Change remove header as desired (search for "Remove_Headers :")
// 7. Change add header as desired (search for "Add_Headers :")

program OnBeforeSendingMessage;

(*
Format for Remove_Headers: {} = required, [] = optional
{HeaderName: }[,HeaderName: ][,HeaderName: ][...]
Examples:
- Single header: 'User-Agent: '
- Multiple headers: 'User-Agent: ,X-Face: '
*)
procedure RemoveHeaders(Message : TStringlist;
const Remove_Headers: String
);
var i : integer;
k : integer;
s : string;
CommaPos : integer;
DelHeader : TStringlist;
RemoveH : String;
begin
RemoveH := Remove_Headers;
i := 0;
(Message.Strings[i] ) + 2 );
i := i - 1;
k := DelHeader.Count - 1;
message.text := s;
end; // if
k := k + 1;
end; // while
i := i + 1;
end; //while
message.text:=s;
finally
DelHeader.Free;
end; // try - finally
end; // if
end; // RemoveHeaders

(*
Format for Add_Headers: {} = required, [] = optional
{HeaderName: HeaderValue{#13#10}}[HeaderName: HeaderValue{#13#10}][...]
Examples: (each header must end with CR+LF)
- Single header: 'User-Agent: '#13#10
- Multiple headers: 'User-Agent: MyNewsClient'#13#10'X-Comment: To be, or
not to be'#13#10

WARNING: For the Add_Header, you MUST add the pound13-Pound10 as shown in
the examples!
If you forget to add the #13#10, then Dialog will error when you send news
saying something like:
Posting article failed: 437 Space before colon in "On Fri, 6 Jan 2017"
header;
*)
procedure AddHeaders(var Message : TStringlist;
const Add_Headers: String
);
var
SeparatorIndex: integer;
s: string;
begin
s:= Message.Text;
// writetolog('***before***'#13#10+s, 7);
SeparatorIndex:= pos(#13#10#13#10, s);
Insert(Add_Headers, s, SeparatorIndex+2);
Message.Text:= s;
// writetolog('***after***'#13#10+s, 7);
end;

function StrMatch(str: String; pattern: String):Boolean;
var
patternSize : Integer;
subStr : String;
compareRes : Integer;
begin
patternSize := Length(pattern);
subStr := Copy(str, 1, patternSize);
compareRes := CompareStr(pattern, subStr);
if (compareRes = 0) then
result := true
else
result := false;
end;

//the xxx2Identity() functions must return an empty string if specified
string is not identified

function From2Identity(from: String): String;
begin
if (StrMatch(from, 'First1 Last1 <ema...@example.com>')) then
result := 'id1'
else if (StrMatch(from, 'First2 Last2 <ema...@example.com>')) then
result := 'id2'
else if (StrMatch(from, 'First3 Last3 <ema...@example.com>')) then
result := 'id3'
else
result := '';
end;

function NewsGroup2Identity(newsgroup: String): String;
// news.software.readers,alt.windows7.general
//SYNTAX: if (StrMatch(newsgroup, 'ng1') or StrMatch(newsgroup, 'ng2'))
then
begin
if (StrMatch (newsgroup, 'news.software.readers') or StrMatch(newsgroup,
'alt.free.newssservers')) then
result := 'id1'
else if StrMatch(newsgroup, 'alt.free.newsservers') then
result := 'id2'
else if StrMatch(newsgroup, 'alt.test') then
result := 'id3'
else
result := '';
end;

function Server2Identity(server: String): String;
begin
if (CompareStr(server, 'aioe_119') = 0) then
result := 'id1'
else if (CompareStr(server, 'mixmin_563') = 0) then
result := 'id2'
else
result := '';
end;

procedure GetIdentities(var message: TStringlist; servername: string;
isEmail: boolean; var FromIdentity: String; var NewsgroupIdentity:
String;
var ServerIdentity: String);
var i : Integer;
begin
FromIdentity := '';
NewsgroupIdentity := '';
ServerIdentity := '';
if (not IsEmail) then
begin
for i := 0 to Message.Count - 1 do
begin
if (strMatch(Message[i], 'From:')) then
fromIdentity := Copy(Message[i], 7, Length(Message[i]) - 6);
if (strMatch(Message[i], 'Newsgroups:')) then
newsgroupIdentity := Copy(Message[i], 13, Length(Message[i]) - 12);
end;
fromIdentity := From2Identity(fromIdentity);
newsgroupIdentity := NewsGroup2Identity(newsgroupIdentity);
serverIdentity := Server2Identity(servername);
// The lines below write to the log file of the format
./40tude/logs/20161231.log
WriteToLog(' fromIdentity = ' + fromIdentity, 7);
WriteToLog(' newsgroupIdentity = ' + newsgroupIdentity, 7);
WriteToLog(' serverIdentity = ' + serverIdentity, 7);
end;
end;

procedure LogHeaders(var Message: TStringlist);
var
i: integer;
s: string;
begin
s:= '';
for i:= 0 to message.count-1 do
begin
if message[i] <> '' then s:= s+message[i]+#13#10
else break;
end;
writetolog(s, 7);
end;

function OnBeforeSendingMessage(var Message : TStringlist;
Servername : string;
IsEmail : boolean
):boolean;
var
ForEmail: boolean;
ForNewsgroup : boolean;
FromIdentity: String;
NewsgroupIdentity: String;
ServerIdentity: String;
Remove_Headers: String;
Add_Headers: String;
begin
//get the identities of the message
GetIdentities(message, servername, isEmail, FromIdentity,
NewsgroupIdentity, ServerIdentity);

// Four program decisions to be made if you wish to change the program
defaults:
// 1. This Boolean sets whether email headers are modified:
// ForEmail := false; //false means don't do email message by
default
// ForEmail := true; //true means do email headers
// 2. This Boolean sets whether newsgroup headers are modified:
// ForNewsgroup := false; //false means don't do newsgroup message by
default
// ForNewsgroup := true; //true means do newsgroup messages
// 3. This string syntax sets the default headers to remove (if not
redefined):
// Remove_Headers := ''; //null means don't remove any header by
default
// Remove_Headers := 'User-Agent: ,Message-ID: '; //string means remove
these headers
// 4. This string syntax sets the default headers to add (if not
redefined):
// Add_Headers := ''; //null means don't add any header by default
// Add_Headers := 'X-Comment: John Doe was here'; //string means add
these header strings
ForEmail := false; //false means don't do email message by default
ForNewsgroup := true; //true means do newsgroup messages
Remove_Headers := ''; //null means don't remove any header by default
Add_Headers := ''; //null means don't add any header by default

{The main decision.

For FromIdentity, comparison must match against string returned by
From2Identity() function.
Same applies to NewsgroupIdentity and ServerIdentity.
Note that identities may be an empty string.

Set Remove_Header to remove header(s).
Set Add_Header to add header(s).
Set ForEmail and/or ForNewsgroup to `true` to add/remove header for
email/newsgroup messages.
}
// Remove_Headers := 'User-Agent: ,Message-ID: ,Date: ,Mime-Version:
,Content-Type: ,Content-Transfer-Encoding: ';
if FromIdentity = 'id1' then
begin
ForNewsgroup := true;
Remove_Headers := 'User-Agent: ,Message-ID: ';
Remove_Headers := 'User-Agent: ,Message-ID: ,Date: ,Mime-Version:
,Content-Type: ,Content-Transfer-Encoding: ';
Add_Headers := 'X-Comment: JJ is a veritable genius!'#13#10;
end
else if (FromIdentity = 'id2') and (NewsgroupIdentity = 'id1') then
begin
ForNewsgroup := true;
Remove_Headers := 'User-Agent: ,Content-Transfer-Encoding: '
Add_Headers := 'X-Comment: John Doe was here'#13#10;
end
else if (FromIdentity = 'id3') and (ServerIdentity = 'id2') then
begin
ForEmail := true;
ForNewsgroup := true;
Remove_Headers := 'User-Agent: ,Mime-Version: ';
Add_Headers := 'X-Comment: Jane Doe was here'#13#10 +
'X-Greeting: Hello there!'#13#10;
end;

if (IsEmail and ForEmail) or ((not IsEmail) and ForNewsgroup) then
begin
if Remove_Headers <> '' then RemoveHeaders(Message, Remove_Headers);
if Add_Headers <> '' then AddHeaders(Message, Add_Headers);
end;

result := true;
// result := false; //uncomment this line for testing purposes (doesn't
send the message)

JJ

unread,
Jan 6, 2017, 4:57:31 AM1/6/17
to
Good to know that it works for you.

One thing you should know is that the `StrMatch()` function compares the
`Pattern` argument against the start of the `str` argument. So when you use
the function to compare the `newsgroup` argument in the
`NewsGroup2Identity()` function, and the message was posted to multiple
newsgroups, that function can only check the first listed newsgroup.

For example, suppose you're using the function like so:

if StrMatch(newsgroup, 'news.software.readers') then //...

If the contents of the newsgroup variable is:

alt.test, news.software.readers

Then the above check will never match.

For the sake of flexibility, here's a function that work like `StrMatch()`
but the pattern can match anywhere in the string being searched. i.e. the
pattern can be at start, at middle, or at end. String comparison is case
sensitive, just like `StrMatch()` does.

function StrContains(const Str: string; const Pattern: string): boolean;
begin
result:= pos(Pattern, Str) > 0;
end;

Insert it into anywhere in the script outside of any other function and use
it just like `StrMatch()`. e.g.

if StrContains(newsgroup, 'news.software.readers') or
StrContains(newsgroup, 'alt.windows7.general') then //...

Stijn De Jong

unread,
Jan 6, 2017, 5:35:29 PM1/6/17
to
On Fri, 6 Jan 2017 16:57:31 +0700, you wrote:

> Good to know that it works for you.

Thank you JJ for rewriting the script so that it's useful!
You are a great Usenet citizen in that you give back to the group.

I realized, in my tests, that there was some funny stuff going on, but I
wasn't sure what the funny stuff was.

So a few mistakes I made were:
a. I couldn't get the string match on multiple newsgroups working
(Now I know why, based on what you wrote below!)
b. I couldn't add certain headers (e.g., NNTP-Posting-Host).
(I suspect that's an NNTP RFC spec that prevents that from working)
c. I couldn't get a WriteLn(Add_Header) to write to the message window.
(The WriteToLog worked but it wrote to the log file instead.)

It's clear you tested the script well since your logic is more flexible
than the original two scripts were.

1. You placed the remove_headers variable in both a syntactically correct
and logically correct location!
2. You added the capability to crosscheck based on any one, two, or three
combinations of identity, and/or server, and/or newsgroup.
3. You added the ability to add headers (and you resolved the non-intuitive
requirement for pound13-pound10 CR+LF syntax), particularly for multiple
headers being added.
4. You added variables so that reasonable defaults exist if someone does
not wish to change any of the variables.
5. And you provided useful working syntactical examples, so that noobs
(like I am) can more easily intuit settings that are syntactically correct!

Overall, your efforts should help anyone, and particularly those who have
different requirements for news/email for personal versus business needs.

> One thing you should know is that the `StrMatch()` function compares the
> `Pattern` argument against the start of the `str` argument. So when you use
> the function to compare the `newsgroup` argument in the
> `NewsGroup2Identity()` function, and the message was posted to multiple
> newsgroups, that function can only check the first listed newsgroup.

Thank you for pointing that out because that string-match was driving me
nuts!

So are you saying that, functionally, these two command are, in effect,
exactly the same functionality?
A. if (StrMatch (newsgroup, 'news.software.readers') or
StrMatch (newsgroup, 'alt.free.newsservers')) then
result := 'id1'
B. if StrMatch(newsgroup, 'news.software.readers') then
result := 'id1'

Is it that both A & B above will only set the result to "id1" if
"news.software.readers" is the first newsgroup in the outgoing Newsgroups:
header?

Asked another way, are you saying that only the first outgoing header line
below will be matched by either of the two commands above?
Newsgroups: news.software.readers,alt.free.newsservers
Newsgroups: alt.free.newsservers,news.software.readers

> For example, suppose you're using the function like so:
>
> if StrMatch(newsgroup, 'news.software.readers') then //...
>
> If the contents of the newsgroup variable is:
>
> alt.test, news.software.readers
>
> Then the above check will never match.

I see. You just answered my questions above!
Thank you for being clear.
I have now modified the comments so that others aren't confused like I was.

> For the sake of flexibility, here's a function that work like `StrMatch()`
> but the pattern can match anywhere in the string being searched. i.e. the
> pattern can be at start, at middle, or at end. String comparison is case
> sensitive, just like `StrMatch()` does.
>
> function StrContains(const Str: string; const Pattern: string): boolean;
> begin
> result:= pos(Pattern, Str) > 0;
> end;
>
> Insert it into anywhere in the script outside of any other function and use
> it just like `StrMatch()`. e.g.
>
> if StrContains(newsgroup, 'news.software.readers') or
> StrContains(newsgroup, 'alt.windows7.general') then //...

I just added your new "string contains" function, and a call to it as
follows. If this post works, then the vignette below worked.

function StrContains(const Str: string; const Pattern: string): boolean;
begin
result:= pos(Pattern, Str) > 0;
end;

function NewsGroup2Identity(newsgroup: String): String;
// WARNING: The StrMatch function can only check the first listed
newsgroup!
// Define a StrContains function if you want to match either/or newsgroups!
// function StrContains(const Str: string; const Pattern: string): boolean;
// begin
// result:= pos(Pattern, Str) > 0;
// end;
// EXAMPLE: This StrMatch will only match the first newsgroup in the
outgoing Newsgroup header!
// if (StrMatch (newsgroup, 'news.software.readers') or StrMatch(newsgroup,
'alt.free.newsservers')) then
// If defined, this StrContains will match either newsgroup or both in the
outgoing Newsgroup header:
// if StrContains(newsgroup, 'news.software.readers') or
StrContains(newsgroup, 'alt.free.newssservers') then
begin
if StrContains(newsgroup, 'news.software.readers') or
StrContains(newsgroup, 'alt.free.newssservers') then
result := 'id1'
else if StrMatch(newsgroup, 'alt.comp.os.windows-10') then
result := 'id2'
else if StrMatch(newsgroup, 'alt.os.linux') then

Stijn De Jong

unread,
Jan 6, 2017, 6:17:56 PM1/6/17
to
On Fri, 6 Jan 2017 22:35:25 +0000 (UTC), you wrote:

> I just added your new "string contains" function, and a call to it as
> follows. If this post works, then the vignette below worked.

To give back to everyone for JJ's helpful improvements, here is the newly
modified code that worked to send this message and the last message.

http://pastebin.com/sgVDqcqu

============ or you can cut here for that code =================
// JJAddAndRemoveHeadersWhileDoubleCheckingIdentityNgAndServers
// This script will add & remove headers based on a decision tree.
// It will also check for mistakes between business & personal use.
// http://pastebin.com/sgVDqcqu (latest revision)
// <http://pastebin.com/2tMYRKM4> older version
// From: JJ <jj4p...@vfemail.net>
// Newsgroups: news.software.readers,alt.windows7.general
// Subject: Re: Request help with 40tude dialog program syntax
// Date: Thu, 5 Jan 2017 23:06:19 +0700
// Message-ID: <7vpx5y09pu98.1sukl5d600sda$.d...@40tude.net>
// Original code for just checking identity, ng, and servers:
// http://dialog.datalist.org/scripts/CheckingIdentity.html
// Original code for just removing headers:
// http://dialog.datalist.org/scripts/RemoveHeaders.html
// NOTES:
// The StrMatch fct is case sensitive and only matches the 1st item found!
// Define a StrContains fct to match multiple either/or newsgroups.
// If you don't set Remove_Header, then none will be removed.
// If you don't set Add_Header, then none will be added.
// For some headers you have to remove them first, then add them back.
// Dialog will error when sending if you add headers sans (CR+LF) syntax!
// WriteLn doesn't seem to do anything.
// CUSTOMIZATION ORDER OF OPERATIONS:
// 1. Set "ForNewsgroup" Boolean as desired (search for "ForNewsgroup :")
// 2. Set "ForEmail" Boolean as desired (search for "ForEmail :")
// 3. Change identity(ies) as desired (search for "from,")
// 4. Change newsgroup(s) as desired (search for "newsgroup,")
// 5. Change server(s) as desired (search for "server,")
// 6. Change remove header(s) as desired (search for "Remove_Headers :")
// 7. Change add header(s) as desired (search for "Add_Headers :")
// End of initial comments.
// Customize your identity below for personal or business use as needed.
// The string match is probably case sensitive!
function From2Identity(from: String): String;
begin
if (StrMatch(from, 'First1 Last1 <ema...@domain.net>')) then
result := 'id1'
else if (StrMatch(from, 'First2 Last2 <ema...@domain.net>')) then
result := 'id2'
else if (StrMatch(from, 'First3 Last3 <ema...@domain.net>')) then
result := 'id3'
else
result := '';
end;

// WARNING: The StrMatch function can only check the first listed
newsgroup!
// Define a StrContains function if you want to match either/or newsgroups!
// function StrContains(const Str: string; const Pattern: string): boolean;
// begin
// result:= pos(Pattern, Str) > 0;
// end;
// EXAMPLE: This StrMatch will only match the first newsgroup in the
outgoing Newsgroup header!
// if (StrMatch (newsgroup, 'news.software.readers') or StrMatch(newsgroup,
'alt.free.newsservers')) then result := 'id1'
// If defined, this StrContains will match either newsgroup or both in the
outgoing Newsgroup header:
// if StrContains(newsgroup, 'news.software.readers') or
StrContains(newsgroup, 'alt.free.newssservers') then result := 'id1'
// End of comments

function StrContains(const Str: string; const Pattern: string): boolean;
begin
result:= pos(Pattern, Str) > 0;
end;

function NewsGroup2Identity(newsgroup: String): String;
begin
if StrContains(newsgroup, 'ng1') or StrContains(newsgroup, 'ng2') then
result := 'id1'
else if StrMatch(newsgroup, 'ng3') then
result := 'id2'
else if StrMatch(newsgroup, 'ng4') then
result := 'id3'
else
result := '';
end;

// The name of the server is what Dialog lists in the "Available Servers"
UI.
function Server2Identity(server: String): String;
begin
if (CompareStr(server, 'eternal september') = 0) then
result := 'id1'
else if (CompareStr(server, 'albasani_119') = 0) then
result := 'id2'
else
result := '';
end;

procedure GetIdentities(var message: TStringlist; servername: string;
isEmail: boolean; var FromIdentity: String; var NewsgroupIdentity:
String;
var ServerIdentity: String);
var i : Integer;
begin
FromIdentity := '';
NewsgroupIdentity := '';
ServerIdentity := '';
if (not IsEmail) then
begin
for i := 0 to Message.Count - 1 do
begin
if (strMatch(Message[i], 'From:')) then
fromIdentity := Copy(Message[i], 7, Length(Message[i]) - 6);
if (strMatch(Message[i], 'Newsgroups:')) then
newsgroupIdentity := Copy(Message[i], 13, Length(Message[i]) - 12);
end;
fromIdentity := From2Identity(fromIdentity);
newsgroupIdentity := NewsGroup2Identity(newsgroupIdentity);
serverIdentity := Server2Identity(servername);
// The default log file is C:/Program Files/40tude/logs/YYYYMMDD.log
ForNewsgroup := true; //true means do newsgroup messages
Remove_Headers := ''; //null means don't remove any header by default
Remove_Headers := 'User-Agent: ,Message-ID: ,Date: '; //remove these
outgoing headers
Add_Headers := ''; //null means don't add any header by default

{The main decision.

For FromIdentity, comparison must match against string returned by
From2Identity() function.
Same applies to NewsgroupIdentity and ServerIdentity.
Note that identities may be an empty string.

Set Remove_Header to remove header(s).
Set Add_Header to add header(s).
Set ForEmail and/or ForNewsgroup to `true` to add/remove header for
email/newsgroup messages.
}

// EXAMPLES:
// Remove_Headers := 'User-Agent: ,Message-ID: ,Date: ,Mime-Version:
,Content-Type: ,Content-Transfer-Encoding: ';
// Add_Headers := 'Organization: none whatsoever'#13#10;
// Add_Headers := 'X-Comment: Jane Doe was here'#13#10 + 'X-Greeting: Hello
there!'#13#10;
// Note that some headers cannot be set (for example, NNTP Posting Host or
Newsgroups)
//
if FromIdentity = 'id1' then
begin
ForNewsgroup := true;
Remove_Headers := 'User-Agent: ,Message-ID: ';
// Add_Headers := 'X-Comment: Jane Doe was here'#13#10 + 'X-Greeting:
Hello there!'#13#10;

end
else if (FromIdentity = 'id2') and (NewsgroupIdentity = 'id2') then
begin
ForNewsgroup := true;
// Remove_Headers := 'User-Agent: ,Content-Transfer-Encoding: '
Add_Headers := 'Organization: none whatsoever'#13#10;
end

else if (FromIdentity = 'id3') and (ServerIdentity = 'id1') then
begin // id3
ForEmail := true;
ForNewsgroup := true;
Remove_Headers := 'User-Agent: ,Mime-Version: ';
Add_Headers := 'User-Agent: My user agent is 40Tude Dialog on Windows
10'#13#10;
// WriteLn(Remove_Headers); // This WriteLn command does not seem to do
anything.
// WriteLn(Add_Headers); // This WriteLn command does not seem to do
anything.
end; // id3

JJ

unread,
Jan 7, 2017, 4:00:33 PM1/7/17
to
On Fri, 6 Jan 2017 22:35:25 +0000 (UTC), Stijn De Jong wrote:
> b. I couldn't add certain headers (e.g., NNTP-Posting-Host).
> (I suspect that's an NNTP RFC spec that prevents that from working)

That's correct. The server may also place additional restrictions on which
headers and their contents. e.g. the email in the "From" header must match
with the email used to register an account from a newsgroups provider.

> c. I couldn't get a WriteLn(Add_Header) to write to the message window.
> (The WriteToLog worked but it wrote to the log file instead.)

This is a technical problem which is not well explained in Dialog's
"Scripting" documentation page. There's a line that says "Only available in
script called from the main GUI thread for thread safety" which refers to
the `Application`, `Screen`, `Timer1`, and `Timer2` global variables, but
actually, the WriteLn() function is one of them too. i.e. they are usable
from the main thread, and the OnBeforeSendingMessage, OnBeforeSavingMessage,
etc., are executed from a (separate) worker thread, which isn't the main
thread.

> So are you saying that, functionally, these two command are, in effect,
> exactly the same functionality?
> A. if (StrMatch (newsgroup, 'news.software.readers') or
> StrMatch (newsgroup, 'alt.free.newsservers')) then
> result := 'id1'
> B. if StrMatch(newsgroup, 'news.software.readers') then
> result := 'id1'
>
> Is it that both A & B above will only set the result to "id1" if
> "news.software.readers" is the first newsgroup in the outgoing Newsgroups:
> header?

[A] and [B] are different because [A] has two conditions to check, and [B]
only has one.

[A] will set the result to "id1" if the first newsgroup in the Newsgroups
header is "news.software.readers" or "alt.free.newsservers".

[B] will set the result to "id1" if the first newsgroup in the Newsgroups
header is "news.software.readers".

> Asked another way, are you saying that only the first outgoing header line
> below will be matched by either of the two commands above?
> Newsgroups: news.software.readers,alt.free.newsservers
> Newsgroups: alt.free.newsservers,news.software.readers

[A] will set the result to "id1" for Newsgroups header #1 and #2.
First StrMatch() matches header #1, and second StrMatch() matches header#2.

[B] will set the result to "id1" for Newsgroups header #1.

Here's some simpler examples for the basic of StrMatch().

These will return `true`:

StrMatch('abc', 'abc') //"abc" is at start of "abc"
StrMatch('abc', 'ab') //"ab" is at start of "abc"
StrMatch('abc', 'a') //"a" is at start of "abc"

These will return `false`:

StrMatch('abc', 'abcd') //"abcd" is not at start of "abc"
StrMatch('abc', 'bc') //"bc" is not at start of "abc"
StrMatch('abc', 'b') //"b" is not at start of "abc"
StrMatch('abc', 'c') //"c" is not at start of "abc"

> I just added your new "string contains" function, and a call to it as
> follows. If this post works, then the vignette below worked.
[snip]
> if StrContains(newsgroup, 'news.software.readers') or
> StrContains(newsgroup, 'alt.free.newssservers') then
> result := 'id1'
> else if StrMatch(newsgroup, 'alt.comp.os.windows-10') then
> result := 'id2'
> else if StrMatch(newsgroup, 'alt.os.linux') then
> result := 'id3'
> else
> result := '';

The first if-then statement (or command) would work as expected, but the
second and the third ones may fail if a message is posted to multiple
newsgroups because they still use the StrMatch() function. i.e.

This won't to set the result to "id2" if the Newsgroups header is
"Newsgroups: news.software.readers,alt.comp.os.windows-10".
It will only set the result if the header is
"Newsgroups: alt.comp.os.windows-10,news.software.readers".

//...
else if StrMatch(newsgroup, 'alt.comp.os.windows-10') then
result := 'id2'
//...

And this won't to set the result to "id3" if the Newsgroups header is
"Newsgroups: alt.comp.os.windows-10,alt.os.linux".
It will only set the result if the header is
"Newsgroups: alt.os.linux,alt.comp.os.windows-10".

//...
else if StrMatch(newsgroup, 'alt.os.linux') then
result := 'id3'
//...


PS) The scripting language used by Dialog is Delphi which is based on the
Pascal programming language. You can use Free Pascal Compiler (FPC)
documentations if you have any interest on understanding the Pascal
programming language. You can also ask Pascal/Delphi related question to
comp.lang.pascal.delphi.misc.

Stijn De Jong

unread,
Jan 7, 2017, 5:57:47 PM1/7/17
to
On Sun, 8 Jan 2017 04:00:31 +0700, you wrote:

>> b. I couldn't add certain headers (e.g., NNTP-Posting-Host).
>> (I suspect that's an NNTP RFC spec that prevents that from working)
>
> That's correct. The server may also place additional restrictions on which
> headers and their contents. e.g. the email in the "From" header must match
> with the email used to register an account from a newsgroups provider.

Thank you JJ for confirming, as anyone who is a noob (like I am) would have
similar questions as I have, so, it's great to flesh them out for the deja
news record (should others search in the future for this topic).

>> c. I couldn't get a WriteLn(Add_Header) to write to the message window.
>> (The WriteToLog worked but it wrote to the log file instead.)
>
> This is a technical problem which is not well explained in Dialog's
> "Scripting" documentation page. There's a line that says "Only available in
> script called from the main GUI thread for thread safety" which refers to
> the `Application`, `Screen`, `Timer1`, and `Timer2` global variables, but
> actually, the WriteLn() function is one of them too. i.e. they are usable
> from the main thread, and the OnBeforeSendingMessage, OnBeforeSavingMessage,
> etc., are executed from a (separate) worker thread, which isn't the main
> thread.

OMG. That's complicated. I think I'll take the simple road, which is to
just remove the WriteLn altogether! :)

I just wanted to see what was happening real time without having to dig
into the log file.

I looked for an option to at least change the location of the log file.
http://dialog.datalist.org/faq/frequently_asked_questions.html

But I gave up as it doesn't seem to be an option to change the location of
the log file, and nobody else seems to have asked that question yet.

> [A] will set the result to "id1" if the first newsgroup in the Newsgroups
> header is "news.software.readers" or "alt.free.newsservers".
>
> [B] will set the result to "id1" if the first newsgroup in the Newsgroups
> header is "news.software.readers".

Oh. I get it. < slaps head >

It's amazing how you interpret differently what I interpret, but your
interpretation makes much more programming sense than does mine!

> Here's some simpler examples for the basic of StrMatch().
> These will return `true`:
> StrMatch('abc', 'abc') //"abc" is at start of "abc"
> StrMatch('abc', 'ab') //"ab" is at start of "abc"
> StrMatch('abc', 'a') //"a" is at start of "abc"
> These will return `false`:
> StrMatch('abc', 'abcd') //"abcd" is not at start of "abc"
> StrMatch('abc', 'bc') //"bc" is not at start of "abc"
> StrMatch('abc', 'b') //"b" is not at start of "abc"
> StrMatch('abc', 'c') //"c" is not at start of "abc"

Thanks for those illustrative examples, which make sense.
I added them, verbatim, a comments to my version of the code, for future
reference.

>> I just added your new "string contains" function, and a call to it as
>> follows. If this post works, then the vignette below worked.
> [snip]
>> if StrContains(newsgroup, 'news.software.readers') or
>> StrContains(newsgroup, 'alt.free.newssservers') then
>> result := 'id1'
>> else if StrMatch(newsgroup, 'alt.comp.os.windows-10') then
>> result := 'id2'
>> else if StrMatch(newsgroup, 'alt.os.linux') then
>> result := 'id3'
>> else
>> result := '';
>
> The first if-then statement (or command) would work as expected, but the
> second and the third ones may fail if a message is posted to multiple
> newsgroups because they still use the StrMatch() function. i.e.

Thanks for that clarification and correction that StrMatch is problematic
even if it only contains one newsgroup because it depends on the order of
the newsgroups in the Newsgroup: header line.

I'll modify my version of the code so that it uses StrContains instead of
StrMatch (which seems far too limited for this purpose so I wonder why the
original contained StrMatch in the first place).

function StrContains(const Str: string; const Pattern: string): boolean;
begin
result:= pos(Pattern, Str) > 0;
end;

function NewsGroup2Identity(newsgroup: String): String;
begin
if StrContains(newsgroup, 'news.software.readers') or
StrContains(newsgroup, 'alt.free.newssservers') then
result := 'id1'
else if StrContains(newsgroup, 'alt.comp.os.windows-10') then
result := 'id2'
else if StrContains(newsgroup, 'alt.os.linux') then
result := 'id3'
else
result := '';
end;


> PS) The scripting language used by Dialog is Delphi which is based on the
> Pascal programming language. You can use Free Pascal Compiler (FPC)
> documentations if you have any interest on understanding the Pascal
> programming language. You can also ask Pascal/Delphi related question to
> comp.lang.pascal.delphi.misc.

Thank you for that advice.
I've added it as a comment to the code I maintain for future use.

Stijn De Jong

unread,
Jan 7, 2017, 7:29:23 PM1/7/17
to
On Sat, 7 Jan 2017 22:57:43 +0000 (UTC), you wrote:

> I've added it as a comment to the code I maintain for future use.

Here is the latest code with all your comments added, and,
with suggestions by Bernd Rose in another thread in the a.s.r newsgroups
also added.

http://pastebin.com/6Md5m67X


========= < obligatory cut here > ============
// JJAddAndRemoveHeadersWhileCheckingNewsgroupsIdentitiesAndServers
// version 1.00 January 8th 2017 "http://pastebin.com/6Md5m67X"
// version 0.02 "http://pastebin.com/sgVDqcqu"
// version 0.01 "http://pastebin.com/2tMYRKM4"
// From: JJ <jj4p...@vfemail.net>
// Newsgroups: news.software.readers,alt.windows7.general
// Subject: Re: Request help with 40tude dialog program syntax
// Date: Thu, 5 Jan 2017 23:06:19 +0700
// Message-ID: <7vpx5y09pu98.1sukl5d600sda$.d...@40tude.net>
// Original code for just checking identity, ng, & servers:
// http://dialog.datalist.org/scripts/CheckingIdentity.html
// Original code for just removing headers:
// http://dialog.datalist.org/scripts/RemoveHeaders.html
// This script will add & remove headers based on a decision tree.
// It will also check for mistakes between business & personal use.
// DOCUMENTATION:
// The scripting language used by Dialog is Delphi which is based on the
// Pascal programming language. You can use Free Pascal Compiler (FPC)
// documentations if you have any interest on understanding the Pascal
// programming language. You can also ask Pascal/Delphi related question to
// comp.lang.pascal.delphi.misc.
// NOTES:
// The original StrMatch fct is case sensitive & matches only the 1st item
found!
// Instead, we define a StrContains fct to match multiple either/or
newsgroups.
// CAVEATS:
// For some headers you have to remove them first, then add them back.
// Dialog will error when sending if you add headers sans (CR+LF) syntax!
// CUSTOMIZATION: Search for "CUSTOMIZATION:"
// 1. Set the "ForNewsgroup" Boolean as desired (search for "ForNewsgroup
:")
// 2. Set the "ForEmail" Boolean as desired (search for "ForEmail :")
// 3. Change identity(ies) as desired (search for "from,")
// 4. Change newsgroup(s) as desired (search for "newsgroup,")
// 5. Change server(s) as desired (search for "server,")
// 6. Change remove header(s) as desired (search for "Remove_Headers :")
// 7. Change add header(s) as desired (search for "Add_Headers :")
// OPTIONS:
// If you don't set Remove_Header, then none will be removed.
// If you don't set Add_Header, then none will be added.
// End of initial comments

program OnBeforeSendingMessage;

(*
Format for Remove_Headers: {} = required, [] = optional
{HeaderName: }[,HeaderName: ][,HeaderName: ][...]
Examples:
- Single header: 'User-Agent: '
- Multiple headers: 'User-Agent: ,X-Face: '
*)

// The user is not expected to need to customize "RemoveHeaders()".
Posting article failed: 437 Space before colon in "On Fri, 6 Jan 2017"
header;
*)

// The user is not expected to need to customize "AddHeaders()".
procedure AddHeaders(var Message : TStringlist;
const Add_Headers: String
);
var
SeparatorIndex: integer;
s: string;
begin
s:= Message.Text;
// writetolog('***before***'#13#10+s, 7);
SeparatorIndex:= pos(#13#10#13#10, s);
Insert(Add_Headers, s, SeparatorIndex+2);
Message.Text:= s;
// writetolog('***after***'#13#10+s, 7);
end;

// The user is not expected to need to customize "StrMatch()".
// WARNING: The StrMatch function can only check the first listed
newsgroup!
// Define a StrContains function if you want to match either/or newsgroups!
// function StrContains(const Str: string; const Pattern: string): boolean;
// begin
// result:= pos(Pattern, Str) > 0;
// end;
// These will return `true`:
// StrMatch('abc', 'abc') //"abc" is at start of "abc"
// StrMatch('abc', 'ab') //"ab" is at start of "abc"
// StrMatch('abc', 'a') //"a" is at start of "abc"
// These will return `false`:
// StrMatch('abc', 'abcd') //"abcd" is not at start of "abc"
// StrMatch('abc', 'bc') //"bc" is not at start of "abc"
// StrMatch('abc', 'b') //"b" is not at start of "abc"
// StrMatch('abc', 'c') //"c" is not at start of "abc"
// EXAMPLE: This StrMatch will only match if either n.s.r or a.f.n is the
*first* ng in the Newsgroups header:
// if (StrMatch (newsgroup, 'news.software.readers') or StrMatch(newsgroup,
'alt.free.newsservers')) then result := 'id1'
// If defined, this StrContains will match either newsgroup or both in the
outgoing Newsgroup header:
// if StrContains(newsgroup, 'news.software.readers') or
StrContains(newsgroup, 'alt.free.newssservers') then result := 'id1'
// End of comments
function StrMatch(str: String; pattern: String):Boolean;
var
patternSize : Integer;
subStr : String;
compareRes : Integer;
begin
patternSize := Length(pattern);
subStr := Copy(str, 1, patternSize);
compareRes := CompareStr(pattern, subStr);
if (compareRes = 0) then
result := true
else
result := false;
end;

// CUSTOMIZATION: identity id1, id2, etc.
// The user is expected to modify to their own identity(ies) below.
//the xxx2Identity() functions must return an empty string if specified
string is not identified
// This is probably case sensitive!
function From2Identity(from: String): String;
begin

if (StrMatch(from, 'First1 Last1 <ema...@domain.com>')) then
result := 'id1'
else if (StrMatch(from, 'First2 Last2 <ema...@domain.com>')) then
result := 'id2'
else if (StrMatch(from, 'First3 Last3 <ema...@domain.com>')) then
result := 'id3'
else
result := '';
end;

// The user is not expected to need to customize "StrContains()".
function StrContains(const Str: string; const Pattern: string): boolean;
begin
result:= pos(Pattern, Str) > 0;
end;

// CUSTOMIZATION: newsgroups ng1, ng2, etc.
// The user is expected to modify to their own newsgroup(s) below.
function NewsGroup2Identity(newsgroup: String): String;
begin
if StrContains(newsgroup, 'ng1') or StrContains(newsgroup, 'ng2') then
result := 'id1'
else if StrContains(newsgroup, 'ng3') then
result := 'id2'
else if StrContains(newsgroup, 'ng4') then
result := 'id3'
else
result := '';
end;

// CUSTOMIZATION: servers server1, server2, etc.
// The user is expected to modify to their own server(s) below.
// The name of the server is what Dialog lists in the "Available Servers"
GUI
function Server2Identity(server: String): String;
begin
if (CompareStr(server, 'server1') = 0) then
result := 'id1'
else if (CompareStr(server, 'server2') = 0) then
result := 'id2'
else
result := '';
end;

// The user is not expected to need to customize "GetIdentities()".
procedure GetIdentities(var message: TStringlist; servername: string;
isEmail: boolean; var FromIdentity: String; var NewsgroupIdentity:
String;
var ServerIdentity: String);
var i : Integer;
begin
FromIdentity := '';
NewsgroupIdentity := '';
ServerIdentity := '';
if (not IsEmail) then
begin
for i := 0 to Message.Count - 1 do
begin
if (strMatch(Message[i], 'From:')) then
fromIdentity := Copy(Message[i], 7, Length(Message[i]) - 6);
if (strMatch(Message[i], 'Newsgroups:')) then
newsgroupIdentity := Copy(Message[i], 13, Length(Message[i]) - 12);
end;
fromIdentity := From2Identity(fromIdentity);
newsgroupIdentity := NewsGroup2Identity(newsgroupIdentity);
serverIdentity := Server2Identity(servername);
// The default log file is C:/Program Files/40tude/logs/YYYYMMDD.log
WriteToLog(' fromIdentity = ' + fromIdentity, 7);
WriteToLog(' newsgroupIdentity = ' + newsgroupIdentity, 7);
WriteToLog(' serverIdentity = ' + serverIdentity, 7);
// Note that "WriteLn" will never work so don't even think of using it.
end;
end;

// The user is not expected to need to customize "LogHeaders()".
// CUSTOMIZATION: main decision tree
// The user is expected to wish to customize this main decision tree.
//get the identities of the message
GetIdentities(message, servername, isEmail, FromIdentity,
NewsgroupIdentity, ServerIdentity);

// Four program decisions to be made if you wish to change the program
defaults:
// 1. This Boolean sets whether email headers are modified:
// ForEmail := false; //false means don't do email message by
default
// ForEmail := true; //true means do email headers
// 2. This Boolean sets whether newsgroup headers are modified:
// ForNewsgroup := false; //false means don't do newsgroup message by
default
// ForNewsgroup := true; //true means do newsgroup messages
// 3. This string syntax sets the default headers to remove (if not
redefined):
// Remove_Headers := ''; //null means don't remove any header by
default
// Remove_Headers := 'User-Agent: ,Message-ID: '; //string means remove
these headers
// 4. This string syntax sets the default headers to add (if not
redefined):
// Add_Headers := ''; //null means don't add any header by default
// Add_Headers := 'X-Comment: John Doe was here'; //string means add
these header strings
// NOTE: By default, 40Tude-Dialog generates a dialog-specific message id.
// You can turn off this message-id autogeneration in the Dialog GUI.
// Or you can remove that message-id after the fact in this script.
// NOTE: By default, 40Tude-Dialog sends the system date to the news
server.
// The news server will use that system date in the Date: header.
// The news server will generate a GMT date if there is no Date:
header.
//
// DEFAULT SETTINGS:
ForEmail := false; //false means don't do email message by default
ForNewsgroup := true; //true means do newsgroup messages
Remove_Headers := ''; //null means don't remove any header by default
Remove_Headers := 'User-Agent: ,Message-ID: ,Date: '; //remove these
outgoing headers by default
Add_Headers := ''; //null means don't add any header by default

{The main decision.

For FromIdentity, comparison must match against string returned by
From2Identity() function.
Same applies to NewsgroupIdentity and ServerIdentity.
Note that identities may be an empty string.

Set Remove_Header to remove header(s).
Set Add_Header to add header(s).
Set ForEmail and/or ForNewsgroup to `true` to add/remove header for
email/newsgroup messages.
}

// EXAMPLES:
// Remove_Headers = 'User-Agent: ';
// Remove_Headers = 'X-Newsreader: ,X-Scoring: ';
// Remove_Headers := 'Message-ID: ,Date: ,Mime-Version: ,Content-Type:
,Content-Transfer-Encoding: ';
//
// Add_Headers := 'User-Agent: slrn/1.0.2 (Darwin)'#13#10;
// Add_Headers := 'Organization: DNLA GmbH'#13#10;
// Add_Headers := 'MIME-Version: 1.0'#13#10 + 'Content-Type: text/plain;
charset=UTF-8'#13#10;
//
if FromIdentity = 'id1' then
begin
ForNewsgroup := true;
Remove_Headers := 'User-Agent: ,Message-ID: ';
end // id1

else

if (FromIdentity = 'id2') and (NewsgroupIdentity = 'id2') then
//else if (FromIdentity = 'id2') then
begin
ForNewsgroup := true;
Remove_Headers := 'User-Agent: ,Content-Transfer-Encoding: '
Add_Headers := 'X-Comment: Caveat emptor!'#13#10;
end // id2

else

if (FromIdentity = 'id3') and (NewsgroupIdentity = 'id2') and
(ServerIdentity = 'id1') then
// else if (FromIdentity = 'id3') and (NewsgroupIdentity = 'id3') and
(Server = 'id3') then
begin
ForEmail := true;
ForNewsgroup := true;
Add_Headers := 'X-Comment: Jane Doe was here'#13#10 + 'X-Greeting:
Hello there!'#13#10;
end; // id3

if (IsEmail and ForEmail) or ((not IsEmail) and ForNewsgroup) then
begin
if Remove_Headers <> '' then RemoveHeaders(Message, Remove_Headers);
if Add_Headers <> '' then AddHeaders(Message, Add_Headers);
end;

result := true;
// result := false; //uncomment this line for testing purposes (doesn't
send the message)
end;
// ----------------------------------------------------------------------
begin
end.
========= < obligatory cut here > ============

JJ

unread,
Jan 8, 2017, 8:32:37 AM1/8/17
to
On Sun, 8 Jan 2017 00:29:20 +0000 (UTC), Stijn De Jong wrote:
>
> GetIdentities(message, servername, isEmail, FromIdentity,
> NewsgroupIdentity, ServerIdentity);
>

Whoops. That line (at start of OnBeforeSendingMessage) should have been:

GetIdentities(message, servername, true, FromIdentity,
NewsgroupIdentity, ServerIdentity);

i.e. the third parameter should be `true` instead of `isEmail`, so that the
function works for both newsgroup and email message. Previously, it won't
work if the message being sent is an email.

I hope that's the last of my goofs.

PS) Please post the script to PasteBin instead of newsgroup, because long
lines got broken into separate lines. It can cause syntax error when
compiled if the script was copy+pasted from the newsgroup message.

Bernd Rose

unread,
Jan 8, 2017, 4:15:36 PM1/8/17
to
On Sun, 8th Jan 2017 20:32:35 +0700, JJ wrote:

> Please post the script to PasteBin instead of newsgroup, because long
> lines got broken into separate lines. It can cause syntax error when
> compiled if the script was copy+pasted from the newsgroup message.

Line wrap can be prevented in Dialog by adding a wrap-override character
via menu <Special><Insert Wrap override character> as first character of
each line. (Or for a whole block of selected text.) These characters will
not be transmitted. But they tell Dialog to exclude the marked lines from
automatic line wraps. (Useful not only for source code with long lines,
but also for long URL strings.)

Depending on the view settings of a receiving client, lines may /appear/
wrongly wrapped, nevertheless. But toggling of "wrapped view" (<Ctrl><w>
in Dialog) or copy/paste into the Scripting Editor (or any other editor)
should show the long lines unwrapped, again.

Bernd

tlvp

unread,
Jan 8, 2017, 5:00:07 PM1/8/17
to
On Sun, 8 Jan 2017 22:15:35 +0100, Bernd Rose wrote:

> Line wrap can be prevented in Dialog by adding a wrap-override character
> via menu <Special><Insert Wrap override character> as first character of
> each line. (Or for a whole block of selected text.) These characters will
> not be transmitted. But they tell Dialog to exclude the marked lines from
> automatic line wraps. ...
>
> Depending on the view settings of a receiving client, lines may /appear/
> wrongly wrapped, nevertheless. But toggling of "wrapped view" (<Ctrl><w>
> in Dialog) or copy/paste into the Scripting Editor (or any other editor)
> should show the long lines unwrapped, again.

Many thanks, Bernd, for that valuable little New Year's tidbit :-) ! A
tweak that's easily overlooked. Carefully noted for future reference.

Cheers, -- tlvp
--
Avant de repondre, jeter la poubelle, SVP.

Stijn De Jong

unread,
Jan 8, 2017, 8:31:24 PM1/8/17
to
On Sun, 8 Jan 2017 22:15:35 +0100, you wrote:

> Line wrap can be prevented in Dialog by adding a wrap-override character
> via menu <Special><Insert Wrap override character> as first character of
> each line. (Or for a whole block of selected text.) These characters will
> not be transmitted. But they tell Dialog to exclude the marked lines from
> automatic line wraps. (Useful not only for source code with long lines,
> but also for long URL strings.)

I am attempting that suggestion in this post.
Compose: Special > Insert Wrap override character


// JJAddAndRemoveHeadersWhileCheckingNewsgroupsIdentitiesAndServers
// version 1.01 January 9th 2017 "http://pastebin.com/A4Aq0T6T"
// version 1.00 January 8th 2017 "http://pastebin.com/6Md5m67X"
// version 0.02 "http://pastebin.com/sgVDqcqu"
// version 0.01 "http://pastebin.com/2tMYRKM4
// version 0.00 From: JJ <jj4p...@vfemail.net>
// Newsgroups: news.software.readers,alt.windows7.general
// Subject: Re: Request help with 40tude dialog program syntax
// Date: Thu, 5 Jan 2017 23:06:19 +0700
// Message-ID: <7vpx5y09pu98.1sukl5d600sda$.d...@40tude.net>
// Original code for just checking identity, ng, & servers:
// http://dialog.datalist.org/scripts/CheckingIdentity.html
// Original code for just removing headers:
// http://dialog.datalist.org/scripts/RemoveHeaders.html
// Library of 40Tude-Dialog scripts:
// http://dialog.datalist.org/scripts/script_library.html
// This script below will add & remove headers based on a decision tree.
// It will also check for mistakes between business & personal use.
// The decision tree is up to you where working examples are provided.
// DOCUMENTATION:
// The scripting language used by Dialog is Delphi which is based on the
// Pascal programming language. You can use Free Pascal Compiler (FPC)
// documentations if you have any interest on understanding the Pascal
// programming language. You can also ask Pascal/Delphi related question to
// comp.lang.pascal.delphi.misc.
// OPTIONS: Search for "CUSTOMIZATION:"
// 1. Set the "ForNewsgroup" Boolean as desired (search for "ForNewsgroup :")
// Generic default is: true
// 2. Set the "ForEmail" Boolean as desired (search for "ForEmail :")
// Generic default is: false
// 3. Change identity(ies) as desired (search for "from,")
// Generic defaults are set to: id1, id2, id3, id4, & id5
// A sample value is: Kilroy <kil...@example.com>
// 4. Change newsgroup(s) as desired (search for "newsgroup,")
// Generic defaults are set to: ng1, ng2, ng3, ng4, & ng5
// A sample value is: news.software.readers
// 5. Change server(s) as desired (search for "server,")
// Generic defaults are set to: server1, server2, server3, server4, server5
// A sample value is: Aioe (it should be whatever you've named it)
// 6. Change remove header(s) as desired (search for "Remove_Headers :")
// Generic defaults are set to remove no headers.
// Generic defaults are set to remove the 6 most common headers.
// A sample value is: Remove_Headers := 'User-Agent: '
// 7. Change add header(s) as desired (search for "Add_Headers :")
// Generic defaults are set to add back no headers.
// A sample value is Add_Headers := 'User-Agent: 40tude_Dialog/2.0.15.84'#13#10;
// 8. Modify the if-then-else program control as needed.
// Generic defaults are simply examples of your desired decision tree.
// NOTES:
// If you set Remove_Header to nothing, then none will be removed.
// If you set Add_Header to nothing, then none will be added.
// For some headers you have to remove them first, then add them back.
// Dialog will error when sending if you add headers sans (CR+LF) syntax!
// The original StrMatch fct is case sensitive & matches only the 1st item found!
// Instead, we define a StrContains fct to match multiple either/or newsgroups.
else if (StrMatch(from, 'First4 Last4 <ema...@domain.com>')) then
result := 'id4'
else if (StrMatch(from, 'First5 Last5 <ema...@domain.com>')) then
result := 'id5'
else if (StrMatch(from, 'First6 Last6 <ema...@domain.com>')) then
result := 'id6'
GetIdentities(message, servername, true, FromIdentity, NewsgroupIdentity, ServerIdentity);
// Four program decisions to be made if you wish to change the program defaults:
// 1. This Boolean sets whether email headers are modified:
// ForEmail := false; //false means don't do email message by default
// ForEmail := true; //true means do email headers
// 2. This Boolean sets whether newsgroup headers are modified:
// ForNewsgroup := false; //false means don't do newsgroup message by default
// ForNewsgroup := true; //true means do newsgroup messages
// 3. This string syntax sets the default headers to remove (if not redefined):
// Remove_Headers := ''; //null means don't remove any header by default
// Remove_Headers := 'User-Agent: ,Message-ID: '; //string means remove these headers
// 4. This string syntax sets the default headers to add (if not redefined):
// Add_Headers := ''; //null means don't add any header by default
// Add_Headers := 'X-Comment: John Doe was here'; //string means add these header strings
// NOTE: By default, 40Tude-Dialog generates a dialog-specific message id.
// You can turn off this message-id autogeneration in the Dialog GUI.
// Or you can remove that message-id after the fact in this script.
// NOTE: By default, 40Tude-Dialog sends the system date to the news server.
// The news server will use that system date in the Date: header.
// The news server will generate a GMT date if there is no Date: header.
//
// DEFAULT SETTINGS:
ForEmail := false; //false means don't do email message by default
ForNewsgroup := true; //true means do newsgroup messages
Remove_Headers := ''; //null means don't remove any header by default
Add_Headers := ''; //null means don't add any header by default

{The main decision.

For FromIdentity, comparison must match against string returned by From2Identity() function.
Same applies to NewsgroupIdentity and ServerIdentity.
Note that identities may be an empty string.

Set Remove_Header to remove header(s).
Set Add_Header to add header(s).
Set ForEmail and/or ForNewsgroup to `true` to add/remove header for email/newsgroup messages.
}

// EXAMPLES:
// Remove_Headers = 'User-Agent: ';
// Remove_Headers = 'X-Newsreader: ,X-Scoring: ';
// Remove_Headers := 'Date: ,Mime-Version: ,Content-Type: ,Content-Transfer-Encoding: ';
//
// Add_Headers := 'User-Agent: 40tude_Dialog/2.0.15.84'#13#10;
// Add_Headers := 'Organization: none'#13#10 + 'X-Comment: As always, YMMV'#13#10;
// Add_Headers := 'Mime-Version: 1.0'#13#10 + 'Content-Type: text/plain; charset="US-ASCII"'#13#10 + 'Content-Transfer-Encoding: 7bit'#13#10;
// NOTES:
// You can't set some headers that the server wants to set (e.g., NNTP-Posting-HOST).
// If nothing is specified NNTP defaults to 'Content-Type: text/plain; charset=US-ASCII' + 'Content-Transfer-Encoding: 7bit'.
//
if FromIdentity = 'id1' then
begin
ForNewsgroup := true;
Remove_Headers = 'User-Agent: ';
Add_Headers := 'User-Agent: 40tude_Dialog/2.0.15.84'#13#10;
end // id1

else

if (FromIdentity = 'id2') and (NewsgroupIdentity = 'id2') then
begin
ForNewsgroup := true;
Remove_Headers = 'X-Newsreader: ,X-Scoring: ';
Add_Headers := 'Organization: none'#13#10 + 'X-Comment: As always, YMMV'#13#10;
end // id2

else

if (FromIdentity = 'id3') and (NewsgroupIdentity = 'id3') and (Server = 'id3') then
begin
ForEmail := false;
ForNewsgroup := true;
Remove_Headers := 'Date: ,Mime-Version: ,Content-Type: ,Content-Transfer-Encoding: ';
Add_Headers := 'Mime-Version: 1.0'#13#10 + 'Content-Type: text/plain; charset="US-ASCII"'#13#10 + 'Content-Transfer-Encoding: 7bit'#13#10;
end // id3

else

if (FromIdentity = 'id4') and (NewsgroupIdentity = 'id3') then
begin
ForNewsgroup := true;
Remove_Headers := ''; //null means don't remove any header by default
Add_Headers := ''; //null means don't add any header by default
end // id4

else

if (FromIdentity = 'id5') and (NewsgroupIdentity = 'id4') and (ServerIdentity = 'id3') then
begin
ForNewsgroup := true;
// If you don't have a Remove_Headers line, then it will use the default.
// If you don't have an Add_Headers line, then it will use the default.
end // id5

else

if (FromIdentity = 'id6') and (ServerIdentity = 'id1') then
begin
ForNewsgroup := true;
Remove_Headers := 'User-Agent: ,Message-ID: ,Date: ,Mime-Version: ,Content-Type: ,Content-Transfer-Encoding: ';
Add_Headers := 'User-Agent: 40tude_Dialog/2.0.15.41'#13#10 + 'Content-Type: text/plain; charset="US-ASCII"'#13#10 + 'Content-Transfer-Encoding: 7bit'#13#10;
end; // id6

Stijn De Jong

unread,
Jan 8, 2017, 8:32:59 PM1/8/17
to
On Sun, 8 Jan 2017 20:32:35 +0700, you wrote:

> Whoops. That line (at start of OnBeforeSendingMessage) should have been:
>
> GetIdentities(message, servername, true, FromIdentity,
> NewsgroupIdentity, ServerIdentity);
>
> i.e. the third parameter should be `true` instead of `isEmail`, so that the
> function works for both newsgroup and email message. Previously, it won't
> work if the message being sent is an email.
>
> I hope that's the last of my goofs.
>
> PS) Please post the script to PasteBin instead of newsgroup, because long
> lines got broken into separate lines. It can cause syntax error when
> compiled if the script was copy+pasted from the newsgroup message.

To give back to the ng, here is the update, with many new explanatory
comments also added.

Stijn De Jong

unread,
Jan 8, 2017, 8:45:17 PM1/8/17
to
On Sun, 8 Jan 2017 17:00:04 -0500, you wrote:

> Many thanks, Bernd, for that valuable little New Year's tidbit :-) ! A
> tweak that's easily overlooked. Carefully noted for future reference.

I had never noticed those five composition options before.
http://i.imgsafe.org/2ea9c372ca.jpg

40Tude: Compose: Special >

1. Reformat paragraph
2. Insert Wrap override character (Shift+Ctrl+O)
3. Insert spoiler character (Ctrl+L)
4. Expand glossary (Ctrl+E)
5. Locate original post/email

Stijn De Jong

unread,
Jan 8, 2017, 9:48:12 PM1/8/17
to
On Sun, 8 Jan 2017 20:32:35 +0700, you wrote:

> Whoops. That line (at start of OnBeforeSendingMessage) should have been:
>
> GetIdentities(message, servername, true, FromIdentity,
> NewsgroupIdentity, ServerIdentity);
>
> i.e. the third parameter should be `true` instead of `isEmail`, so that the
> function works for both newsgroup and email message. Previously, it won't
> work if the message being sent is an email.
>
> I hope that's the last of my goofs.
>
> PS) Please post the script to PasteBin instead of newsgroup, because long
> lines got broken into separate lines. It can cause syntax error when
> compiled if the script was copy+pasted from the newsgroup message.

oh oh

I just tested the procedure with and without that line and I
was surprised that the new line seems to have broken something.

I had to put back the old line to get the program to work again.

In both tests, this was the set of options:
ForEmail := false;
ForNewsgroup := true;

This line worked fine to remove and add desired headers:


GetIdentities(message, servername, isEmail, FromIdentity, NewsgroupIdentity, ServerIdentity);

Changing just to this line caused nothing to happen:
GetIdentities(message, servername, true, FromIdentity, NewsgroupIdentity, ServerIdentity);

So I just now went back to the original call.
0 new messages