Closed gaynetdinov closed 5 months ago
Sorry for the slow response. Yeah, that's a difference between their documented and actual behavior. Their actual behavior is ...weird. :) They don't provide ABNF, but I infer from the docs that their grammar is (or was): x-gm-label = flag / astring
. Net::IMAP consistently converts flag
tokens (eg: \atomchars
with no quotes) into symbols and atom
, astring
, quoted
, or literal
tokens into strings. And I'd prefer that Net::IMAP remain consistent on this, rather than smooth over provider weirdness. There's no semantic difference between word
(atom), "word"
(quoted) or {4}\r\nword
(literal), but we do need to distinqish between \word
(flag) and "\\word"
(quoted).
So, I think the only thing you would need change in your code is to check for "\\Draft"
in addition to (or instead of) :Draft
. Alternatively, you could create a monkey patch like:
class Net::IMAP::ResponseParser
module PatchXGMLabelsAsSymbols
private
def x_gm_labels = super.map { _1.start_with?("\\") ? _1[1..].capitalize.to_sym : _1 }
end
prepend PatchXGMLabelsAsSymbols
end
But that of course comes with all of the standard warnings and caveats about the issues with monkeypatching. 😉
What I'm guessing happened was that they originally wanted to send their localizable system labels (XLIST) as flags and user provided (not localizable) labels as astrings, but then (I'm guessing) they realized that the RFC has this to say about flag-extensions:
Server implementations MUST NOT generate flag-extension flags except as defined by a future Standard or Standards Track revisions of this specification.
...so they had to convert their flags to astrings. But they still need to keep the distinction between their localizable system (XLIST) labels and user-provided (not localizable) labels, so they retained the leading \
inside the astring. But then they never updated the docs! (The docs do claim that the labels are all astrings
, so maybe they partially updated them?) And also, they long ago deprecated XLIST in favor of the standard SPECIAL-USE, so (in as much as that's what they are returning) they really should return any SPECIAL-USE flags as flag
tokens (not astring
).
However, changing the returned values would require incrementing UIDVALIDITY on all affected mailboxes (and clients that depend on the current behavior) so they probably just figured it wasn't worth changing. And anyway, they have a much bigger bug on their PERMANENTFLAGS response which they haven't fixed for two decades now, so... :)
Hey @nevans!
I wanted to share one more imap hack we have in our codebase. This time it was introduced by me in order to deal with inconsistencies that are coming from X-GM-LABELS.
The issue is that people, in fact, can put whatever they want as a label name. Here is example response from my test Gmail account where I created some nonsense labels.
Since our goal was only to determine whether an email is draft email or not, I came up with the following method for net-imap v0.3.7
Since v0.3.7 net-imap got rid of
FLAG_REGEXP
and parsing of X-GM-LABELS is done differently now, but I believe net-imap still would not be able to parse list of Gmail's labels if they contain parentheses or some other special characters.I've seen list of label from X-GM-LABELS that would look like this
(X-GM-LABELS ("Junkmail (filtered)" "[Gmail] (2)/Prod (test)" "\\Draft" "\\Important")
I'm not even sure if one can come up with a regexp that would match any potential label name in the list of X-GM-LABELS. While for our app we don't really need to extract correctly the whole list of X-GM-LABELS I'm curious to make it work. The thing confuses me right now is that in the tests for X-GM-LABEL in net-imap I see this
So the FLAG labels like
\\Inbox
or\\Sent
are not wrapped into double quotes, but when I fetch them from Gmail they are actually wrapped (see my example above). In my experience only simple names likefav
in the example above are not wrapped into"
.Perhaps I'm missing something? Anyways, your feedback or help would be highly appreciated! Thank you for your time!