Subject: draft-melnikov-sieve-imapflags-03.txt

From: Ken Murchison <[email-masked]>
Date: Tue, 08 Aug 2000 12:10:24 -0400

Alexey,

A couple nits/comments/questions on your latest draft:

Where's the page breaks and page headers?  :^)

>    #
>    # Example Sieve Filter
>    # Declare any optional features or extension used by the script
>    #
>    require ["fileinto", "reject", "imapflags"];

Any reason why "reject" is required and mentioned below, but never used?

>    #
>    # Reject any large messages
>    #
>    if size :over 1M
>            {
>            if header :is "From" "[email-masked]"
>                       {
>                       addflag "\\Flagged $Big";

This should be: addflag ["\\Flagged", "$Big"];

>    # The message will be marked as "\Flagged $Big" when filed into mailbox "Big messages"
>                       }
>            fileinto "Big messages";
>            }
> 
>    if header :is "From" "[email-masked]"
>            {
>            addflag ["\\Answered", "$MDNSent"];
>    # If the message is bigger than 1Mb it will be marked as "\Flagged $Big \Answered $MDNSent" 

Unless I'm completely off the mark (and my cmu-sieve implementation is
incorrect), "\Flagged $Big" will never be set on these messages, because
these flags are only set 'if header :is "From" "[email-masked]"'.  I
think you want the first test in the script to be something like:

if size :over 1M
           {
           addflag "\\Flagged $Big";
           if header :is "From" "[email-masked]"
                      {
   # The message will be marked as "\Flagged $Big" when filed into
mailbox "Big messages"
                      fileinto "Big messages";
                      }
           }

>    # when filed into mailbox "grandma". If the message is shorter than 1Mb it will be marked as
>    # "\Answered $MDNSent"
>            fileinto "GrandMa";  # move to "GrandMa" folder
>            }
> 

Ken
-- 
Kenneth Murchison     Oceana Matrix Ltd.
Software Engineer     21 Princeton Place
716-662-8973 x26      Orchard Park, NY 14127
--PGP Public Key--    http://www.oceana.com/~ken/ksm.pgp

---

From: Alexey Melnikov <[email-masked]>
Date: Tue, 08 Aug 2000 22:00:04 -0600

> Where's the page breaks and page headers?  :^)

I've decided to add them at the later stage.

> This should be: addflag ["\\Flagged", "$Big"];

Right.

> these flags are only set 'if header :is "From" "[email-masked]"'.

Correct. Message will be filed into "Big messages" in all cases and only if "from" is
"[email-masked]" two flags will be set.

>  I think you want the first test in the script to be something like:
>
> if size :over 1M
>            {

Alexey

---

From: Tim Showalter <[email-masked]>
Date: 22 Aug 2000 17:13:27 -0700

I may have voiced this before, but I don't remember.

I believe that the right way to set IMAP flags is by an optional
argument on the keep and fileinto commands, not a side effect that
effectively munges a global variable.

My primary problem with the current approach that this is the first
Sieve command to have a side effect that affects another action (other
than the reject vs. keep interaction stuff, which is somewhat more
minor).  The way this stuff interacts is potentially annoying.  Given
the existance of tagged optional arguments in the document as is, I
would prefer a different approach.

Assume for a moment the existance of either functions or a preprocessor,
both things that have been discussed and are likely to be developed
later.  In either case (they're more or less the same without varibles,
anyway), addflag/removeflag/setflag affect global state, and it may not
be obvious how these things interact.

Until now, it has always been safe to add code to the bottom of a script
and assume that that code can stand alone.  However, arbitrary flags can
be added, and there's no way to figure out what flags are set, it is
conceivable for "library" macros to set flags that there is no reliable
way to clear.

I would prefer if fileinto and keep were extended to take an optional
:flags argument which would describe the flags to be added to the
message, i.e.,

        if header :matches "Subject" "ADV:*" {
                keep :flags "\\Deleted" ;
        }

Incidentially, among the nits in v03, the grammar at the end of the
document should be removed entirely.  It doesn't match the Sieve grammar
at all (which doesn't define action, for instance).  It is not
necessary; the existing Sieve grammar encompasses everything represented
here.  However, the "Syntax" lines in the base document need to be
on each command to clarify the types.

Tim

---

From: Alexey Melnikov <[email-masked]>
Date: Thu, 24 Aug 2000 00:22:08 -0600

> effectively munges a global variable.

I like this better but I remeber some objections.
Also it is extremely difficult to explain this "global variable" concept to
non-programmers.

> ...

> be added, and there's no way to figure out what flags are set,

Correct.

> it is conceivable for "library" macros to set flags that there is no
> reliable
> way to clear.

You can always unset all known flags. This is ugly but works.
I miss test for set flags :-(.

> ...

> on each command to clarify the types.

I will look at this.

Alexey

---

From: Ken Murchison <[email-masked]>
Date: Thu, 24 Aug 2000 09:54:38 -0400

> would prefer a different approach.

I agree with this in principal, and would not be opposed to this change.

However, having implemented the current draft in cmu-sieve and being a
user of the functionality, I'll try to make a (possibly weak) case for
why the global variable concept can be advantageous.  Below is a subset
of a script that I currently use:

require ["fileinto", "imapflags", "subaddress"];

# mark (flag) all messages from Tim Showalter
if address :user "from" "tjs" {
  mark;
}

# file mailing list stuff
if address :localpart :is ["to", "from", "cc", "resent-to"]
"ietf-mta-filters" {
  fileinto "INBOX.ietf.mta-filters";
}
elsif address :localpart :is ["to", "from", "cc", "resent-to"]
"ietf-imapext" {
  fileinto "INBOX.ietf.imapext";
}
elsif address :user :is ["to", "from", "cc", "resent-to"] "info-cyrus" {
  fileinto "INBOX.cyrus";
}

The upshot of this is that with only one test at the top of my script, I
can flag all of the *extremely* important messages from Tim regardless
of where they get filed/kept.  If we move the imapflags to an optional
argument, I would have to to a test for "tjs" for every fileinto/keep.

This is the only use of the global variable concept that I have come
across, so if the consensus is to make the change to an optional
argument, I would be inconvenienced, but not overly disappointed.

Ken

---

From: Cyrus Daboo <[email-masked]>
Date: Thu, 24 Aug 2000 11:16:16 -0400

> argument, I would have to to a test for "tjs" for every fileinto/keep.

I agree with Ken on this. I think it is useful to be able to set flags 
globally. I also think its useful to be able to set flags on a one-time 
basis for keep and fileinto commands as well. So I would actually argue for 
both forms of imapflags to be available: as a global command and as a 
parameter for fileinto and keep!

-- 
Cyrus Daboo

---

From: Ken Murchison <[email-masked]>
Date: Thu, 24 Aug 2000 12:12:10 -0400

> parameter for fileinto and keep!

Ooh, I kind of like this!  So the flags specified with :flags would be
the only ones set for that message (as opposed to the union of :flags
and the globals), correct?  What if we have some global flags set, but
want to fileinto/keep WITHOUT any flags?  Would we do this with
something like:

keep :flags [];		or
keep :flags "";		or
keep :flags "None";

Hmmm...  By allowing both types (local and global) we're kind of getting
into scopes here, is this going to get too messy?

Ken

---

From: Cyrus Daboo <[email-masked]>
Date: Thu, 24 Aug 2000 13:23:53 -0400

> want to fileinto/keep WITHOUT any flags?  Would we do this with

We could opt for an IMAP like syntax here:

keep :flags+ [...]  - stored flags are global flags with additional flags

keep :flags- [...]  - stored flags are global flags with some removed

keep :flags [...]   - stored flags are only those listed - global flags are 
ignored

-- 
Cyrus Daboo

---

From: Tim Showalter <[email-masked]>
Date: 24 Aug 2000 13:08:24 -0700

Alexey Melnikov <[email-masked]> writes:

> > reliable way to clear.

That isn't work; if an include system has set a global flag like
"Youll-never-guess-the-name-of-this-flag-Bz28QzBNF", you can't really
reliably unset it.  This is a degenrate case, but it's still kinda bad.

So the other thing that occurred to me is this, and it kinda scares me:
if we're going to go down the path of global variables, we might as well
have a $default_flags global variable and use that along with :flags.
Something tells me that the operations on lists of stuff are going to be
reasonably constant.

I am not convinced of this, but in light of some comments Patrik
Fältström made, we might want to go down the path of variables anyway.
If we're going to, basic list operations are going to be essential as
well.

I believe that if we can choose between setting the default/global flags
and setting flags on a single keep/fileinto, we should go with a single
keep/fileinto, and discuss global flags later.

Tim

---

From: Lawrence Greenfield <[email-masked]>
Date: Thu, 24 Aug 2000 17:13:57 -0400

From: Tim Showalter <[email-masked]>
   Date: 24 Aug 2000 13:08:24 -0700

[...]

I agree with this.  Variables are the Right way to go on this.

Larry

---

From: Alexey Melnikov <[email-masked]>
Date: Sun, 27 Aug 2000 15:19:07 -0600

I am in favour of keeping both syntaxes, because Ken showed usability of glabal
variable use.

> keep :flags [...]   - stored flags are only those listed - global flags are

Sometimes you want to use only global flags, so I would rather the following:

keep :globalflags+ [...]  - stored flags are global flags with additional flags

keep :globalflags- [...]  - stored flags are global flags with some removed

keep :globalflags   - use only global flags

Alexey