Open lukesmurray opened 5 years ago
There are a few issues which come up often when dealing with priority based actions. The first is the issue of when priority is assigned to an email and how to assign ordering to the users functions. If we have triggers going to callbacks then we need to have the callback which sets priority happen before a callback which takes an action based on priority. If these callbacks are subscribed to the same trigger for example on_new_message
then this ordering is undetermined. The simplest answer to this is to have the user put assigning and taking action in the same callback but what happens when priority changes. This brings up the second issue. Some users want to be able to perform an action based on the state of a message changing. For example, 24 hours after a message is read archive it. We currently don't have a way of determining if the state of a message has changed and its not clear to me that it is easy to track state. Subscribing to these state changes is another issue. Another issue I identified is how we can schedule functions to be called. For example set mode to rest and in one hour set mode to working. This might be able to be done with set_interval
but maybe we want to also have a way to say how many times we want the interval to be called.
The last issue is how we want to express sending emails. Sending emails should allow for things like setting to
bcc
cc
fields on the Message
object. But setting these fields for received emails doesn't make sense. Furthermore common actions like forwarding a Message
should be easy. I outlined some issues with this below.
As far as I know I don't think that we can implement or change notifications using our program. Nevertheless these are some common notification use cases.
I also don't think that our program can sort emails. Soya you may know better than me. I've listed the sorting desires here
This section covers the variety of actions expressed in the same manner as the triaging emails section.
This request is asked for a lot so it should be easy to implement.
current implementation
# note that get_labels
if "low" in get_labels():
move("low_priority_email_folder")
threads and messages
# note that this could be the callback from a trigger and might need
# a dependency on the function that assigns priorities
def on_new_message(message):
if "low" in message.labels():
message.move("low_priority_email_folder")
I don't think that this is possible in our current implementation without freezing the system. Freezing the system could occur if the user does something like time.sleep(10000) which they may want to do if it is 9am and they want their code to wait until 3pm to send an email. Also our current implementation doesn't have publicly documented methods for dealing with multiple messages simultaneously.
threads and messages
This implementation is very rough and further thought could be put into it to make it cleaner.
# this could be implemented as a callback from our timer
def every_three_hours():
# use a global mailbox object to access low priority email
# i also ignore filtering only messages received in last three hours for
# brevity
low_priority_messages = mailbox.filter_messages(lambda m: not m.isread() and m.priority() == "low")
my_email = "apples@apples.com"
# here we are faced with decision of if we want our message object
# to be sendable. This would mean properties like to and cc are editable
# which does not make sense on received messages
batch_message = Message()
batch_message.to(my_email)
batch_message.content('\n'.join([m.content() for m in low_priority_messages]))
for this to work as the user intended we probably need some way of being notified that the state of a message has changed, i.e. that it has been opened or read. It's not clear that we can do that but ignoring that problem we also need to figure a way to schedule events.
this is not possible in our current implementation
this runs into the same issue as the previous one
this could be implemented in code or could be done externally through an app. Through code this could be hacked together by doing something like if subject is youps:setMode(lunch). Having rest for one hour relies on scheduling.
current implementation
if get_sender() == "example@apples.com":
send("fwd:" + get_subject(), "recipient@apples.com", get_content())
messages and threads
# this is a clean looking implementation but could become confusing if we add
# things like bcc and cc and want to modify the forwarded message
def on_new_message(message):
if message.sender() == "example@apple.com":
message.forward("recipient@apples.com")
# this implementation makes doing things like adding bcc and cc easier but
# might not conform to IMAP or inherent standards for forwarded messages
def on_new_message(message):
if message.sender() == "example@apples.com":
message_to_forward = Message()
message_to_forward.content(message.content())
message_to_forward.to("recipient@apples.com")
this also relies on a scheduler @soyapark : this type of mutation observer is actually really tricky! It would be easy if users only manipulate emails from YoUPS but they will also use their own email interface to add label and stuff. One way to keep up with these is frequently going over entire messages to detect any property changes. If there is any change, we can update it with a timestamp. Can you think of any better way? @lukesmurray
Two proposals for controlling notifications
It works as following:
Only one drawback here is getting complicated if the user already has other filters. Either option: 1) if the user prioritizes this filter, their Youps filter will be overwritten to their other filters. 2) if the user prioritizes it last, then our notification feature will only work for messages that are arriving at "INBOX" folder.
A benefit is users dont need to set anything. A drawback is users' might get push notifications since users' interface and YoUPS is noticing message arrival at the same time, it would be late for us to turn off the notification.
First implementation containing both messages and threads in #80
I decided to go back to the survey and try to implement some of the requests that people want in order to determine what kind of methods we want on these objects. As you can see some things look really hard to do but what I'm more interested in is your thoughts on the code blocks marked as threads and messages. These are rough drafts of what the new api could look like. Some of my thoughts are listed in plain text or italics while many of the changes I've proposed are explained in the python comments. The bullet points represent tasks which people wanted to do within Triaging. It may be worth submitting this as a pull request so we can comment on the implementations line by line.
Triaging Emails
should we make priority a unique category which would add and remove flags
current implementation
threads and messages
this is currently impossible in our model
threads and messages
we could create a contacts object and use the contacts object in places like
get_recipients
andget_sender
.this is impossible and not simple to implement
current implementation
threads and messages
this brings up the issue of whether
get_recipients
should include cc and bcc. I think it should but we should have separate methodsto
,cc
, andbcc
to access these fields individually.it's unclear to me if we support this in the current implementation
threads and messages
current implementation
threads and messages
the alternative is already covered but it involves getting good interoperability between strings and
Contact
objects.we don't support this currently since we don't have a concept of contacts
even with the concept of a
Contact
object we don't differentiate between people you know and people you just receive emails fromseems hard to implement
already covered how this could be done.
get_subject()
=>message.subect()
we should check how date is returned, I think it should be returned to the user as a
datetime
object. It almost certainly should not be returned to the user as a string since that will be hard to deal with.current implementation
this is either impossible or hard to do in the current implementation it might be possible with searching but would need low level understanding of imap.
threads and messages
this seems hard to implement
it's unclear to me if we can address what a group mail address is csail-related is a group mail address but thats not obvious just from the email address itself
@soyapark @lukesmurray : We can tell if it's a message from a mailing list by inspecting IMAP message properties. One of the properties is
Precedence
. Its value islist
if it's from a mailing list. There are alsoList-Id, List-Unsubscribe, List-Archive, List-Post, List-Help, List-Subscribe
We already have examples of this type of issue above
We already have examples of this above.
maybe our
Contact
object should have a propertydomain
. Other than that this is covered.This is hard to implement without third party information
I don't know if this is possible