Skip to content

Instantly share code, notes, and snippets.

@evandrix
Created December 29, 2013 15:44
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save evandrix/8171623 to your computer and use it in GitHub Desktop.
Save evandrix/8171623 to your computer and use it in GitHub Desktop.
Gmail API

Gmail.js - JavaScript API for Gmail

TL;DR Summary

  • Lots of api methods to work with gmail. Useful for chrome extensions
  • Most of them dont take arguments, they work on what is currently visible on the screen
  • I still need to add implementation for chrome extension, works by injecting js for now
  • Main method is gmail.observe.on('lots_of_actions_here', callback())
  • Click on a method link to view more detailed docs
  • Create an issue/pull request for feedback, requests and fixes

Demo

Here is a demo of it being used in a chrome extension

Setup

Quick Usage - Chrome Console

// {inject jquery.js} by copy pasting this in your console
var jq = document.createElement('script');
jq.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js";
document.getElementsByTagName('body')[0].appendChild(jq);

// {inject gmail.js} by copy pasting gmail.js contents or via url like jquery above
// var Gmail = {.....} // paste gmail.js code here

// start using!
var gmail = Gmail();
gmail.get.user_email();

Methods

Summary (click for more info)

GET

CHECK

OBSERVE

  • gmail.observe .http_requests()
  • gmail.observe .actions()
  • gmail.observe .off(action)
  • gmail.observe .on(action, callback)
    • poll - When gmail automatically polls the server to check for new emails every few seconds
    • new_email - When a new email appears in the inbox
    • open_email - When an email is opened from the inbox view
    • refresh - When you click the refresh button
    • unread - When a conversation(s) is marked unread
    • read - When a conversation(s) is marked read
    • delete - When a conversation(s) is deleted
    • mark_as_spam - When a conversation(s) is marked as spam
    • mark_as_not_spam - When a conversation(s) is unchecked as spam
    • label - When a conversation(s) get applied a label
    • archive - When a conversation(s) is archieved
    • move_to_inbox - When a conversation(s) is moved to the inbox
    • delete_forever - When a conversation(s) is deleted forever
    • star - When a conversation(s) is starred
    • unstar - When a conversation(s) is unstarred
    • mark_as_important - When a conversation(s) is marked as important
    • mark_as_not_important - When a conversation(s) is marked as not important
    • filter_messages_like_these - When a filter button is triggered for a conversation
    • mute - When a conversation(s) is muted
    • unmute - When a conversation(s) is unmuted
    • add_to_tasks - When an item is added to google tasks
    • move_label - When a conversation(s) is moved to a label folder
    • save_draft - When a draft is saved
    • discard_draft - When a draft is dicarded
    • send_message - When a message is sent
    • expand_categories - When a category is expanded from the left nav sidebar
    • delete_label - When a label is deleted
    • show_newly_arrived_message - When inside an email and a new email arrives in the thread

DOM

These methods return the DOM data itself

  • gmail.dom .inboxes()
  • gmail.dom .inbox_content()
  • gmail.dom .email_subject()
  • gmail.dom .email_body()
  • gmail.dom .email_contents()
  • gmail.dom .get_left_sidebar_links()
  • gmail.dom .search_bar()

TOOLS

These are some helper functions that the rest of the methods use. See source for input params

  • gmail.tools .xhr_watcher()
  • gmail.tools .parse_url()
  • gmail.tools .deparam()
  • gmail.tools .parse_view_data()
  • gmail.tools .parse_email_data()
  • gmail.tools .make_request()
  • gmail.tools .sleep(ms)
  • gmail.tools .multitry(ms_delay, tries, func, bool_success_check)

TRACKER

These are some of the variables that are tracked and kept in memory while the rest of the methods are in use.

  • gmail.version
  • gmail.tracker .events
  • gmail.tracker .xhr_init
  • gmail.tracker .xhr_open
  • gmail.tracker .xhr_send
  • gmail.tracker .watchdog
  • gmail.tracker .view_data
  • gmail.tracker .email_data
  • gmail.tracker .ik
  • gmail.tracker .rid

Details

gmail.get.visible_emails()

Returns a list of emails from the server that are currently visible in the inbox view. The data does not come from the DOM

[{"id": "1425a3693a4c45d0",
  "title": "<b>What if video games were real? On YouTube</b>",
  "excerpt": "View email in a web browser Header Super Mario Brothers Parkour by Warialasky Super Mario Brothers",
  "time": "Fri, Nov 15, 2013 at 12:23 AM",
  "sender": "noreply@youtube.com",
  "attachment": "",
  "labels": ["^all", "^i", "^smartlabel_social", "^unsub"]}]

gmail.get.email_data(email_id=undefined)

Returns an object representation of the opened email contents and metadata. It takes the optional email_id parameter where the data for the specified id is returned instead of the email currently visible in the dom

{
  "first_email": "141d44da39d6caf8",
  "last_email": "141d44da39d6caf8",
  "total_emails": 1,
  "total_threads": ["141d44da39d6caf8"],
  "people_involved": [
    ["Kartik Talwar", "hi@kartikt.com"],
    ["California", "california@gmail.com"]
  ],
  "subject": "test",
  "threads": {
    "141d44da39d6caf8": {
      "reply_to_id": "",
      "from": "California",
      "to" : ["hi@kartikt.com"],
      "cc" : [],
      "bcc" : [],
      "from_email": "california@gmail.com",
      "timestamp": 1382246359000,
      "datetime": "Sun, Nov 20, 2013 at 1:19 AM",
      "content_plain": "another test",
      "subject": "test",
      "content_html": "<div dir=\"ltr\">another test</div>\n"
    }
  }
}

gmail.get.user_email()

Returns the current user's email address

"california@gmail.com"

gmail.get.storage_info()

Returns current user's file storage stats

{
  "used": "0 GB",
  "total": "15 GB",
  "percent": 0
}

gmail.get.current_page()

Returns what page of gmail the user is currently on. These are the possible responses

['sent', 'inbox', 'starred', 'drafts', 'imp', 'chats', 'all', 'spam', 'trash'] // pages
null // inside email conversation
"/search/[.+]" // inside search view
"/label/[.+]" // inside label view
"/category/[.+]" // inside category view

gmail.get.email_subject()

Returns the opened email's subject from the DOM

"test"

gmail.get.email_id()

Gets current email's ID

"141de25dc0b48e4f"

gmail.get.email_ids()

Returns a list of email IDs for each thread in the conversation

["141de25dc0b48e4f"]

gmail.get.search_query()

Returns the search bar data

"from:hi@kartikt.com is:unread"

gmail.get.unread_emails()

Returns a count of total unread emails for the current account.

{
  "inbox": 2,
  "drafts": 0,
  "spam": 0,
  "forum": 0,
  "notifications": 0,
  "promotions": 0,
  "social": 0
}

You can also request the data individually

  • gmail.get.unread_inbox_emails()
  • gmail.get.unread_draft_emails()
  • gmail.get.unread_spam_emails()
  • gmail.get.unread_forum_emails()
  • gmail.get.unread_notification_emails()
  • gmail.get.unread_promotion_emails()
  • gmail.get.unread_social_emails()

gmail.get.last_active()

Gets user's account activity data

{
  "time": "9:41 pm",
  "ip": "54.234.192.48",
  "mac_address": "2620:101:f000:702:a966:ab42:4a46:195e",
  "time_relative": "31 minutes ago"
}

gmail.get.loggedin_accounts()

Returns a list of signed-in accounts (multiple user accounts setup in gmail)

[{"name":"California","email":"california@gmail.com"}]

gmail.get.beta()

Although hand picked, this method returns the checks on beta features and deployments

{"new_nav_bar":true}

gmail.check.is_thread()

Returns True if the conversation is threaded False otherwise

gmail.check.is_preview_pane()

Returns True if gmail is in split pane mode (vertical or horizontal) False otherwise

gmail.check.is_multiple_inbox()

Returns True if user has multiple inbox lab enabled, False otherwise

gmail.check.is_horizontal_split()

Returns True if the pane split mode is horiontal False otherwise

gmail.check.is_vertical_split()

Returns True if the pane mode is vertical False otherwise

gmail.check.is_tabbed_inbox()

Returns True if tabbed inbox view is enabled False otherwise

gmail.check.is_right_side_chat()

Returns True if chat is on the right sidebar False otherwise

gmail.check.is_google_apps_user()

Returns True if the current user is google apps user (email not ending in gmail.com) False otherwise

gmail.check.is_inside_email()

Returns True if you are currently inside an email conversation False otherwise

gmail.check.is_priority_inbox()

Returns True if priority inbox is enabled False otherwise

gmail.check.is_rapportive_installed()

Returns True if rapportive chrome extension is installed False otherwise

gmail.check.is_streak_installed()

Returns True if streak chrome extension is installed False otherwise

gmail.check.is_anydo_installed()

Returns True if any.do chrome extension is installed False otherwise

gmail.check.is_boomerang_installed()

Returns True if boomerang chrome extension is installed False otherwise

gmail.check.is_xobni_installed()

Returns True if xobni chrome extension is installed False otherwise

gmail.check.is_signal_installed()

Returns True if Signal chrome extension is installed False otherwise

gmail.observe.http_requests()

After the gmail.obsere.on() has been initiated, this method keeps track of the last 50 http events. The items contain the sent requested parameterized data

[{
  "method": "POST",
  "url": {
    "ui": "2",
    "ik": "13fa7f7088",
    "rid": "ed0e..",
    "view": "tl",
    "start": "0",
    "num": "30",
    "lhop": "169846",
    "ltup": "%5Ei",
    "slmm": "1427abc6106ac10b",
    "scid": "q2h353hw6dv9",
    "avw": "1194",
    "ntlv": "10",
    "auto": "1",
    "ver": "-z-h-bKmWwI.en.",
    "am": "!6hSPXvkvPMjmReGu2-2BQXCk3IltF-jNSk0J8Cg_jNeaoSbpJgHQYdkXe6T_WPYyyATD3DSiOA",
    "vas": "1",
    "ari": "120",
    "_reqid": "4582876",
    "pcd": "1",
    "mb": "0",
    "rt": "j",
    "search": "inbox"
  },
  "body": "",
  "url_raw": "?ui=2&ik=13fa7f7088&rid=ed0e..&view=tl&start=0&num=30&lhop=169846&ltup=%5Ei&slmm=1427abc6106ac10b&scid=q2h353hw6dv9&avw=1194&ntlv=10&auto=1&ver=-z-h-bKmWwI.en.&am=!6hSPXvkvPMjmReGu2-2BQXCk3IltF-jNSk0J8Cg_jNeaoSbpJgHQYdkXe6T_WPYyyATD3DSiOA&vas=1&ari=120&_reqid=4582876&pcd=1&mb=0&rt=j&search=inbox"
}]

gmail.observe.actions()

Similar to gmail.obsere.http_requests() this keeps track of the last 10 gmail actions (vs all http requests). Actions here correspond to things like clicking refres, archiving, deleting, starring etc.

gmail.observe.on(action, callback)

This is the key feature of gmail.js. This method allows you to add triggers to all of these actions so you can build your custom extension/tool with this library.

You simply specify the action nane and your function that the method will return data to when the actions are triggered and it does the rest. You can have multiple triggers

Available Actions

  • poll - When gmail automatically polls the server to check for new emails every few seconds
  • new_email - When a new email appears in the inbox
  • open_email - When a new email appears in the inbox
  • refresh - When you click the refresh button
  • unread - When a conversation(s) is marked unread
  • read - When a conversation(s) is marked read
  • delete - When a conversation(s) is deleted
  • mark_as_spam - When a conversation(s) is marked as spam
  • mark_as_not_spam - When a conversation(s) is unchecked as spam
  • label - When a conversation(s) get applied a label
  • archive - When a conversation(s) is archieved
  • move_to_inbox - When a conversation(s) is moved to the inbox
  • delete_forever - When a conversation(s) is deleted forever
  • star - When a conversation(s) is starred
  • unstar - When a conversation(s) is unstarred
  • mark_as_important - When a conversation(s) is marked as important
  • mark_as_not_important - When a conversation(s) is marked as not important
  • filter_messages_like_these - When a filter button is triggered for a conversation
  • mute - When a conversation(s) is muted
  • unmute - When a conversation(s) is unmuted
  • add_to_tasks - When an item is added to google tasks
  • move_label - When a conversation(s) is moved to a label folder
  • save_draft - When a draft is saved
  • discard_draft - When a draft is dicarded
  • send_message - When a message is sent
  • expand_categories - When a category is expanded from the left nav sidebar
  • delete_label - When a label is deleted
  • show_newly_arrived_message - When inside an email and a new email arrives in the thread
gmail.observe.on("unread", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("read", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("delete", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("mark_as_spam", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("mark_as_not_spam", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("label", function(id, url, body, label) {
  console.log("id:", id, "url:", url, 'body', body, "label", label);
})

gmail.observe.on("archive", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("move_to_inbox", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("delete_forever", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("star", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("unstar", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("mark_as_important", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("mark_as_not_important", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("filter_messages_like_these", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("mute", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("unmute", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("add_to_tasks", function(url, body, data) {
  console.log("url:", url, 'body', body, 'task_data', data);
})

gmail.observe.on("move_label", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("save_draft", function(url, body, data) {
  console.log("url:", url, 'body', body, 'email_data', data);
})

gmail.observe.on("discard_draft", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("send_message", function(url, body, data) {
  console.log("url:", url, 'body', body, 'email_data', data);
})

gmail.observe.on("expand_categories", function(url, body, data) {
  console.log("url:", url, 'body', body, 'expanded_data', data);
})

gmail.observe.on("delete_label", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("show_newly_arrived_message", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("poll", function(url, body, data) {
  console.log("url:", url, 'body', body, 'data', data);
})

gmail.observe.on("new_email", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
})

gmail.observe.on("refresh", function(url, body, data) {
  console.log("url:", url, 'body', body, 'data', data);
})

gmail.observe.on("open_email", function(id, url, body) {
  console.log("id:", id, "url:", url, 'body', body);
  console.log(gmail.get.email_data(id));
})

gmail.observe.off(action=null)

Turn off an observe action. Providing it no argument will disable all observers.

gmail.observe.on('poll', function(x,y,z){});
gmail.observe.on('refresh', function(x,y,z){});

gmail.observe.off('poll'); // disables poll
gmail.observe.off();  // disables both
#!/usr/bin/env python
import pygtk
pygtk.require('2.0')
import gtk
import time
import smtplib
import imaplib
import getpass
import email
import pickle
import base64
import os
from email.MIMEMultipart import MIMEMultipart
from email.Utils import COMMASPACE
from email.MIMEBase import MIMEBase
from email.parser import Parser
from email.MIMEImage import MIMEImage
from email.MIMEText import MIMEText
from email.MIMEAudio import MIMEAudio
import mimetypes
att_filelist=[]
class GUIAPI:
def get_login(self, widget, user_entry, pass_entry, window):
user = user_entry.get_text()
passw = pass_entry.get_text()
window.destroy()
login(user, passw)
def __init__(self):
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_size_request(300, 100)
window.set_title('Gmail API - 1.1')
window.connect('delete_event', lambda w,e : gtk.main_quit())
vbox = gtk.VBox(False, 0)
window.add(vbox)
vbox.show()
user_entry = gtk.Entry()
user_entry.set_max_length(30)
user_entry.set_text('Username')
vbox.pack_start(user_entry, False, False, 0)
user_entry.show()
pass_entry = gtk.Entry()
pass_entry.set_max_length(30)
pass_entry.set_visibility(False)
pass_entry.set_text('password')
vbox.pack_start(pass_entry, False, False, 0)
pass_entry.show()
button = gtk.Button('Sign In')
button.connect('clicked', self.get_login, user_entry, pass_entry, window)
vbox.pack_start(button, False, False, 3)
button.set_flags(gtk.CAN_DEFAULT)
button.grab_default()
button.show()
window.show()
class MainWindow:
def sendmail(self, widget, user, server, window):
window.destroy()
send_mail(user, server)
def __init__(self, user, server, mail):
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_size_request(800, 600)
window.set_title('Gmail API - 1.1')
window.connect('delete_event', lambda w,e : gtk.main_quit())
vbox = gtk.VBox(False, 2)
vbox.set_size_request(800,600)
hbox = gtk.HBox(False, 2)
hbox.set_size_request(800,50)
vbox.pack_start(hbox, False, False, 2)
vpaned = gtk.VPaned()
vbox.add(vpaned)
label = gtk.Label(user)
vpaned.add1(label)
label.show()
panedbox = gtk.HBox(False, 2)
vpaned.add2(panedbox)
panedbox.show()
button = gtk.ToggleButton('Send Mail')
button.connect('toggled', self.sendmail, user, server, window)
button.set_size_request(100,30)
hbox.pack_start(button, False, False, 2)
button.show()
button = gtk.ToggleButton('Recieve Mail')
button.set_size_request(100,30)
# button.connect('toggled', self.callback, 'toggle button 2')
hbox.pack_start(button, False, False, 2)
button.show()
button = gtk.Button('Quit')
button.set_size_request(100,50)
button.connect('clicked', lambda wid: gtk.main_quit())
hbox.pack_end(button, False, False, 2)
button.show()
window.add(vbox)
vpaned.show()
vbox.show()
hbox.show()
window.show()
class PanedWindow:
def sendmail(self, widget, user, server, window):
window.destroy()
send_mail(user, server)
def mailcontent(self, widget, fromaddr_entry, to_entry, sub_entry, textview, filelist, window, user, server):
fromaddr = fromaddr_entry.get_text()
to = to_entry.get_text()
sub = sub_entry.get_text()
textbuffer = textview.get_buffer()
startiter = textbuffer.get_start_iter()
enditer = textbuffer.get_end_iter()
body = textbuffer.get_text(startiter, enditer)
window.destroy()
sendthemail(user, server, fromaddr, to, sub, body, filelist)
gtk.main_quit()
def select_file(self, widget, data = None):
self.filew = gtk.FileSelection('Attach file')
self.filew.ok_button.connect('clicked', self.file_ok_sel)
self.filew.cancel_button.connect("clicked", lambda w: self.filew.destroy())
self.filew.set_filename('Attach File')
self.filew.show()
def file_ok_sel(self, w):
print "%s" % self.filew.get_filename()
att_filelist.append(self.filew.get_filename())
print att_filelist
# append to a list
self.filew.destroy()
def __init__(self, user, server):
att_filelist = []
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_size_request(800, 600)
window.set_title('Gmail API - 1.1')
window.connect('delete_event', lambda w,e : gtk.main_quit())
vbox = gtk.VBox(False, 2)
vbox.set_size_request(800,600)
hbox = gtk.HBox(False, 2)
hbox.set_size_request(800,50)
vbox.pack_start(hbox, False, False, 2)
vbox.show()
vpaned = gtk.VPaned()
vbox.add(vpaned)
label = gtk.Label(user)
vpaned.add1(label)
label.show()
panedbox = gtk.HBox(False, 2)
vpaned.add2(panedbox)
panedbox.show()
button = gtk.ToggleButton('Send Mail')
button.connect('toggled', self.sendmail, user, server, window)
button.set_size_request(100,30)
hbox.pack_start(button, False, False, 2)
button.show()
button = gtk.ToggleButton('Recieve Mail')
button.set_size_request(100,30)
# button.connect('toggled', self.callback, 'toggle button 2')
hbox.pack_start(button, False, False, 2)
button.show()
button = gtk.Button('Quit')
button.set_size_request(100,50)
button.connect('clicked', lambda wid: gtk.main_quit())
hbox.pack_end(button, False, False, 2)
button.show()
window.add(vbox)
pvbox = gtk.VBox(False, 0)
panedbox.add(pvbox)
pvbox.show()
fromaddr_entry = gtk.Entry()
fromaddr_entry.set_max_length(30)
fromaddr_entry.set_text('From')
pvbox.pack_start(fromaddr_entry, False, False, 0)
fromaddr_entry.show()
to_entry = gtk.Entry()
to_entry.set_text('To: ')
pvbox.pack_start(to_entry, False, False, 0)
to_entry.show()
sub_entry = gtk.Entry()
sub_entry.set_max_length(30)
sub_entry.set_text('Subject')
pvbox.pack_start(sub_entry, False, False, 0)
sub_entry.show()
att_file_box = gtk.EventBox()
att_file_box.set_size_request(30,20)
pvbox.pack_start(att_file_box,False, False, 2)
att_file_box.show()
att_file_label = gtk.Label('Attach a file')
att_file_box.add(att_file_label)
att_file_label.show()
att_file_label.set_size_request(10,20)
att_file_box.set_events(gtk.gdk.BUTTON_PRESS_MASK)
att_file_box.connect("button_press_event", self.select_file)
att_file_box.realize()
att_file_box.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND1))
# Set background color to green
att_file_box.modify_bg(gtk.STATE_NORMAL, att_file_box.get_colormap().alloc_color("orange"))
sw = gtk.ScrolledWindow()
sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
textview = gtk.TextView()
textbuffer = textview.get_buffer()
sw.add(textview)
sw.show()
textview.show()
pvbox.pack_start(sw)
textbuffer.set_text('')
send_button = gtk.Button('send')
send_button.set_size_request(400,30)
send_button.connect('clicked', self.mailcontent, fromaddr_entry, to_entry, sub_entry, textview, att_filelist, window, user, server)
pvbox.pack_end(send_button, False, False, 0)
send_button.show()
vpaned.show()
pvbox.show()
hbox.show()
window.show()
def send_mail(user, server):
panedwindow = PanedWindow(user, server)
def sendthemail(user, server, fromaddr, to, sub, body, filelist):
msg = email.MIMEMultipart.MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = to
msg['Subject'] = sub
tolist = to.split()
msg.attach(MIMEText(body))
msg.attach(MIMEText('\nsent via python', 'plain'))
print att_filelist
for i in range(len(att_filelist)):
msg = attach_files(msg, att_filelist[i])
server.sendmail(user,tolist,msg.as_string())
print 'sent'
return
def attach_files(msg, filename):
ctype, encoding = mimetypes.guess_type(filename)
if ctype is None or encoding is not None:
ctype = 'application/octet-stream'
maintype, subtype = ctype.split('/', 1)
f = open(filename, 'rb')
if maintype == 'text':
part = MIMEText(f.read(), _subtype=subtype)
elif maintype == 'image':
part = MIMEImage(f.read(), _subtype=subtype)
elif maintype == 'audio':
part = MIMEAudio(f.read(), _subtype=subtype)
else:
part = MIMEBase(maintype, subtype)
msg.set_payload(f.read())
part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(filename))
msg.attach(part)
f.close()
return msg
def login(user, passw):
smtp_host = 'smtp.gmail.com'
smtp_port = 587
server = smtplib.SMTP()
print 'server created'
server.connect(smtp_host,smtp_port)
server.ehlo()
server.starttls()
server.login(user,passw)
imap_host = 'imap.gmail.com'
mail = imaplib.IMAP4_SSL(imap_host)
mail.login(user,passw)
main_window = MainWindow(user, server, mail)
def main():
win = GUIAPI()
gtk.main()
if __name__ == '__main__':
main()
var Gmail = function() {
var api = {
get : {},
observe : {},
check : {},
tools : {},
tracker : {},
dom : {}
};
api.version = "0.2.2";
api.tracker.globals = GLOBALS;
api.tracker.view_data = VIEW_DATA;
api.tracker.ik = api.tracker.globals[9];
api.get.last_active = function() {
var data = api.tracker.globals[17][15];
return {
time : data[1],
ip : data[3],
mac_address : data[9],
time_relative : data[10]
}
}
api.get.loggedin_accounts = function() {
var data = api.tracker.globals[17][23];
var users = [];
for(i in data[1]) {
users.push({name : data[1][i][4], email : data[1][i][0]})
}
return users;
}
api.get.user_email = function() {
return api.tracker.globals[10];
};
api.check.is_thread = function() {
var check_1 = $('.nH .if').children(":eq(1)").children().children(":eq(1)").children();
var check_2 = api.get.email_ids();
return check_1.length > 1 || check_2.length > 1;
};
api.dom.inbox_content = function() {
return $('div[role=main]:first');
}
api.check.is_preview_pane = function() {
var dom = api.dom.inbox_content();
var boxes = dom.find("[gh=tl]");
var previewPaneFound = false;
boxes.each(function() {
if($(this).hasClass('aia')) {
previewPaneFound = true;
}
});
return previewPaneFound;
}
api.dom.inboxes = function() {
var dom = api.dom.inbox_content();
return dom.find("[gh=tl]");
}
api.check.is_multiple_inbox = function() {
var dom = api.dom.inboxes();
return dom.length > 1;
}
api.check.is_horizontal_split = function() {
var dom = api.dom.inbox_content();
var box = dom.find("[gh=tl]").find('.nn');
return box.length == 0;
}
api.check.is_vertical_split = function() {
return api.check.is_horizontal_split() == false;
}
api.check.is_tabbed_inbox = function() {
return $(".aKh").length == 1;
}
api.check.is_right_side_chat = function() {
return $('.ApVoH')[0].getAttribute('aria-labelledby') == ':wf';
}
api.check.is_google_apps_user =function() {
var email = api.get.user_email();
return email.indexOf('gmail.com', email.length - 'gmail.com'.length) == -1;
}
api.get.storage_info = function() {
var div = $('.md.mj').find('div')[0];
var used = $(div).find('span')[0].innerText;
var total = $(div).find('span')[1].innerText;
var percent = parseFloat(used.replace(/[^0-9\.]/g, '')) * 100 / parseFloat(total.replace(/[^0-9\.]/g, ''));
return {used : used, total : total, percent : Math.floor(percent)}
}
api.dom.email_subject = function () {
return $('h1.ha');
}
api.get.email_subject = function() {
var subject_dom = api.dom.email_subject();
return subject_dom.find('.hP')[0].innerText;
}
api.dom.email_body = function() {
return $('.nH.hx');
}
api.check.is_inside_email = function() {
return api.dom.email_contents().length > 0;
}
api.dom.email_contents = function() {
var items = $('.ii.gt');
var ids = [];
for(var i=0; i<items.length; i++) {
var mail_id = items[i].getAttribute('class').split(' ')[2];
var is_editable = items[i].getAttribute('contenteditable');
if(mail_id != 'undefined' && mail_id != undefined) {
if(is_editable != 'true') {
ids.push(items[i]);
}
}
}
return ids;
}
api.get.email_ids = function() {
if(api.check.is_inside_email()) {
var data = api.get.email_data();
return Object.keys(data.threads);
}
return [];
}
api.get.email_id = function() {
var hash = null;
if(api.check.is_inside_email()) {
if(api.check.is_preview_pane()) {
var items = api.dom.email_contents();
var text = [];
for(var i=0; i<items.length; i++) {
var mail_id = items[i].getAttribute('class').split(' ')[2];
var is_editable = items[i].getAttribute('contenteditable');
if(mail_id != 'undefined' && mail_id != undefined) {
if(is_editable != 'true') {
text.push(mail_id);
}
}
}
hash = text[0].substring(1, text[0].length);
} else {
hash = window.location.hash.split("/").pop().replace(/#/, '').split('?')[0];
}
}
return hash;
}
api.check.is_priority_inbox = function() {
return $('.qh').length > 0;
}
api.check.is_rapportive_installed = function() {
return $('#rapportive-sidebar').length == 1;
}
api.check.is_streak_installed = function() {
return $("[id^='bentoBox'],[id*=' bentoBox'],[class*=' bentoBox'],[class*='bentoBox']").length > 0;
}
api.check.is_anydo_installed = function() {
return $("[id^='anydo'],[id*=' anydo'],[class*=' anydo'],[class*='anydo']").length > 0;
}
api.check.is_boomerang_installed = function() {
return $("[id^='b4g_'],[id*=' b4g_'],[class*=' b4g_'],[class*='b4g_']").length > 0;
}
api.check.is_xobni_installed = function() {
return $('#xobni_frame').length > 0;
}
api.check.is_signal_installed = function() {
return $("[id^='Signal'],[id*=' Signal'],[class*=' signal'],[class*='signal']").length > 0;
}
api.dom.get_left_sidebar_links = function() {
return $("div[role=navigation] [title]");
}
api.dom.search_bar = function() {
return $("[gh=sb]");
}
api.get.search_query = function() {
var dom = api.dom.search_bar();
return dom.find('input')[0].value;
}
api.get.unread_inbox_emails = function() {
var dom = $("div[role=navigation]").find("[title*='Inbox']");
if(dom.length > 0) {
if(dom[0].innerText.indexOf('(') != -1) {
return parseInt(dom[0].innerText.replace(/[^0-9]/g, ''));
}
}
return 0;
}
api.get.unread_draft_emails = function() {
var dom = $("div[role=navigation]").find("[title*='Drafts']");
if(dom.length > 0) {
if(dom[0].innerText.indexOf('(') != -1) {
return parseInt(dom[0].innerText.replace(/[^0-9]/g, ''));
}
}
return 0;
}
api.get.unread_spam_emails = function() {
var dom = $("div[role=navigation]").find("[title*='Spam']");
if(dom.length > 0) {
if(dom[0].innerText.indexOf('(') != -1) {
return parseInt(dom[0].innerText.replace(/[^0-9]/g, ''));
}
}
return 0;
}
api.get.unread_forum_emails = function() {
var dom = $("div[role=navigation]").find("[title*='Forums']");
if(dom.length > 0) {
if(dom[0].innerText.indexOf('(') != -1) {
return parseInt(dom[0].innerText.replace(/[^0-9]/g, ''));
}
}
return 0;
}
api.get.unread_notification_emails = function() {
var dom = $("div[role=navigation]").find("[title*='Notifications']");
if(dom.length > 0) {
if(dom[0].innerText.indexOf('(') != -1) {
return parseInt(dom[0].innerText.replace(/[^0-9]/g, ''));
}
}
return 0;
}
api.get.unread_promotion_emails = function() {
var dom = $("div[role=navigation]").find("[title*='Promotions']");
if(dom.length > 0) {
if(dom[0].innerText.indexOf('(') != -1) {
return parseInt(dom[0].innerText.replace(/[^0-9]/g, ''));
}
}
return 0;
}
api.get.unread_social_emails = function() {
var dom = $("div[role=navigation]").find("[title*='Social Updates']");
if(dom.length > 0) {
if(dom[0].innerText.indexOf('(') != -1) {
return parseInt(dom[0].innerText.replace(/[^0-9]/g, ''));
}
}
return 0;
}
api.get.beta = function() {
var features = {
"new_nav_bar" : $('#gbz').length == 0
}
return features;
}
api.get.unread_emails = function() {
return { inbox : api.get.unread_inbox_emails(),
drafts : api.get.unread_draft_emails(),
spam : api.get.unread_spam_emails(),
forum : api.get.unread_forum_emails(),
notifications : api.get.unread_notification_emails(),
promotions : api.get.unread_promotion_emails(),
social : api.get.unread_social_emails() }
}
api.tools.parse_url = function(url) {
var regex = /[?&]([^=#]+)=([^&#]*)/g;
var params = {};
var match;
while (match = regex.exec(url)) {
params[match[1]] = match[2];
}
return params;
}
api.tools.sleep = function(milliseconds) {
var start = new Date().getTime();
while(true) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
api.tools.multitry = function(delay, tries, func, check, counter, retval) {
if(counter != undefined && counter >= tries) {
return retval;
}
var counter = (counter == undefined) ? 0 : counter;
var value = func();
if(check(value)) {
return value;
} else {
api.tools.sleep(delay)
api.tools.multitry(delay, tries, func, check, counter+1, value)
}
}
api.tools.deparam = function (params, coerce) {
var each = function (arr, fnc) {
var data = [];
for (i = 0; i < arr.length; i++) {
data.push(fnc(arr[i]));
}
return data;
};
var isArray = Array.isArray || function(obj) {
return Object.prototype.toString.call(obj) == '[object Array]';
};
var obj = {},
coerce_types = {
'true': !0,
'false': !1,
'null': null
};
each(params.replace(/\+/g, ' ').split('&'), function (v, j) {
var param = v.split('='),
key = decodeURIComponent(param[0]),
val,
cur = obj,
i = 0,
keys = key.split(']['),
keys_last = keys.length - 1;
if (/\[/.test(keys[0]) && /\]$/.test(keys[keys_last])) {
keys[keys_last] = keys[keys_last].replace(/\]$/, '');
keys = keys.shift().split('[').concat(keys);
keys_last = keys.length - 1;
} else {
keys_last = 0;
}
if (param.length === 2) {
val = decodeURIComponent(param[1]);
if (coerce) {
val = val && !isNaN(val) ? +val : val === 'undefined' ? undefined : coerce_types[val] !== undefined ? coerce_types[val] : val;
}
if (keys_last) {
for (; i <= keys_last; i++) {
key = keys[i] === '' ? cur.length : keys[i];
cur = cur[key] = i < keys_last ? cur[key] || (keys[i + 1] && isNaN(keys[i + 1]) ? {} : []) : val;
}
} else {
if (isArray(obj[key])) {
obj[key].push(val);
} else if (obj[key] !== undefined) {
obj[key] = [obj[key], val];
} else {
obj[key] = val;
}
}
} else if (key) {
obj[key] = coerce ? undefined : '';
}
});
return obj;
}
api.tools.parse_actions = function(params) {
if(params.method == 'POST' && typeof params.url.act == 'string') {
// console.log(params.url, params.body);
}
if(params.url.search != undefined) {
// console.log(params.url, params.body, params.url_raw);
}
var action_map = {
'tae' : 'add_to_tasks',
'rc_^i' : 'archive',
'tr' : 'delete',
'dl' : 'delete_forever',
'dc_' : 'delete_label',
'dd' : 'discard_draft',
'el' : 'expand_categories',
'cffm' : 'filter_messages_like_these',
'arl' : 'label',
'mai' : 'mark_as_important',
'mani' : 'mark_as_not_important',
'us' : 'mark_as_not_spam',
'sp' : 'mark_as_spam',
'mt' : 'move_label',
'ib' : 'move_to_inbox',
'ig' : 'mute',
'rd' : 'read',
'sd' : 'save_draft',
'sm' : 'send_message',
'mo' : 'show_newly_arrived_message',
'st' : 'star',
'ug' : 'unmute',
'ur' : 'unread',
'xst' : 'unstar',
'new_mail' : 'new_email',
'poll' : 'poll',
'refresh' : 'refresh',
'open_email' : 'open_email'
}
if(typeof params.url.ik == 'string') {
api.tracker.ik = params.url.ik;
}
if(typeof params.url.rid == 'string') {
if(params.url.rid.indexOf("mail") != -1) {
api.tracker.rid = params.url.rid;
}
}
var action = decodeURIComponent(params.url.act);
var sent_params = api.tools.deparam(params.body)
var email_ids = (typeof sent_params.t == 'string') ? [sent_params.t] : sent_params.t;
var response = null;
switch(action) {
case "ur" :
var response = [email_ids, params.url, params.body];
break;
case "rd":
var response = [email_ids, params.url, params.body];
break;
case "tr":
var response = [email_ids, params.url, params.body];
break;
case "sp":
var response = [email_ids, params.url, params.body];
break;
case "us":
var response = [email_ids, params.url, params.body];
break;
case "arl":
var response = [email_ids, params.url, params.body, params.url.acn];
break;
case "ib":
var response = [email_ids, params.url, params.body];
break;
case "dl":
var response = [email_ids, params.url, params.body];
break;
case "st":
var response = [email_ids, params.url, params.body];
break;
case "xst":
var response = [email_ids, params.url, params.body];
break;
case "mai":
var response = [email_ids, params.url, params.body];
break;
case "mani":
var response = [email_ids, params.url, params.body];
break;
case "ig":
var response = [email_ids, params.url, params.body];
break;
case "ug":
var response = [email_ids, params.url, params.body];
break;
case "sd":
var response = [email_ids, params.url, sent_params];
break;
case "dd":
var response = [email_ids, params.url, params.body];
break;
case "mt":
var response = [email_ids, params.url, params.body];
break;
case "tae":
var response = [params.url, params.body, sent_params];
break;
case "cffm":
var response = [email_ids, params.url, params.body];
break;
case "rc_^i":
var response = [email_ids, params.url, params.body];
break;
case "sm":
var response = [params.url, params.body, sent_params];
break;
case "el":
var response = [params.url, params.body, sent_params.ex == '1'];
break;
}
if(typeof params.url._reqid == 'string' && typeof params.url.th == 'string') {
var response = [params.url.th, params.url, params.body];
if('new_email' in api.tracker.watchdog) {
api.tracker.watchdog['new_email'].apply(undefined, response);
}
}
if((params.url.view == 'cv' || params.url.view == 'ad') && typeof params.url.th == 'string' && typeof params.url.search == 'string') {
var response = [params.url.th, params.url, params.body];
if('open_email' in api.tracker.watchdog) {
api.tracker.watchdog['open_email'].apply(undefined, response);
}
}
if(typeof params.url.SID == 'string' && typeof params.url.zx == 'string' && params.body.indexOf('req0_') != -1) {
api.tracker.SID = params.url.SID;
var response = [params.url, params.body, sent_params];
if('poll' in api.tracker.watchdog) {
api.tracker.watchdog['poll'].apply(undefined, response);
}
}
if(typeof params.url.ik == 'string' && typeof params.url.search == 'string' && params.body.length == 0 && typeof params.url._reqid == 'string') {
var response = [params.url, params.body, sent_params];
if('refresh' in api.tracker.watchdog) {
api.tracker.watchdog['refresh'].apply(undefined, response);
}
}
if(response != null) {
if(action_map[action] in api.tracker.watchdog) {
api.tracker.watchdog[action_map[action]].apply(undefined, response);
}
}
}
api.tools.parse_requests = function(params) {
params.url_raw = params.url;
params.url = api.tools.parse_url(params.url);
if(typeof api.tracker.events != 'object' && typeof api.tracker.actions != 'object') {
api.tracker.events = [];
api.tracker.actions = [];
}
api.tracker.events.unshift(params);
api.tools.parse_actions(params);
if(params.method == 'POST' && typeof params.url.act == 'string') {
api.tracker.actions.unshift(params);
}
if(api.tracker.events.length > 50) {
api.tracker.events.pop();
}
if(api.tracker.actions.length > 10) {
api.tracker.actions.pop();
}
}
api.tools.xhr_watcher = function () {
var self = this;
if (!api.tracker.xhr_init) {
var win = top.document.getElementById("js_frame").contentDocument.defaultView;
api.tracker.xhr_init = true;
api.tracker.xhr_open = win.XMLHttpRequest.prototype.open;
api.tracker.xhr_send = win.XMLHttpRequest.prototype.send;
win.XMLHttpRequest.prototype._gjs_open = win.XMLHttpRequest.prototype.open;
win.XMLHttpRequest.prototype.open = function (method, url, async, user, password) {
var out = this._gjs_open.apply(this, arguments);
this.xhrParams = {
method: method.toString(),
url: url.toString()
};
return out;
};
win.XMLHttpRequest.prototype._gjs_send = win.XMLHttpRequest.prototype.send;
win.XMLHttpRequest.prototype.send = function (body) {
var out = this._gjs_send.apply(this, arguments);
if (this.xhrParams) {
this.xhrParams.body = body;
api.tools.parse_requests(this.xhrParams);
}
return out;
}
}
}
api.observe.http_requests = function() {
return api.tracker.events;
}
api.observe.actions = function() {
return api.tracker.actions;
}
api.observe.on = function(action, callback) {
if(typeof api.tracker.watchdog != "object") {
api.tracker.watchdog = {};
}
if(!api.tracker.xhr_init) {
api.tools.xhr_watcher();
}
api.tracker.watchdog[action] = callback;
}
api.observe.off = function(action) {
if(action) {
if('watchdog' in api.tracker) {
if(action in api.tracker.watchdog) {
delete api.tracker.watchdog[action];
}
}
} else {
var win = top.document.getElementById("js_frame").contentDocument.defaultView;
win.XMLHttpRequest.prototype.open = api.tracker.xhr_open;
win.XMLHttpRequest.prototype.send = api.tracker.xhr_send;
api.tracker.xhr_init = false
}
}
api.tools.make_request = function (link, method) {
var method = (typeof method == undefined || typeof method == null) ? 'GET' : method;
var request = $.ajax({ type: method, url: encodeURI(link), async:false });
return request.responseText;
}
api.tools.parse_view_data = function(view_data) {
var parsed = [];
var data = [];
for(var j=0; j < view_data.length; j++) {
if(view_data[j][0] == 'tb') {
for(var k=0; k < view_data[j][2].length; k++) {
data.push(view_data[j][2][k]);
}
}
}
for(var i=0; i < data.length; i++) {
var x = data[i];
var temp = {};
parsed.push({
id: x[0],
title : x[9],
excerpt : x[10],
time : x[15],
sender : x[28],
attachment : x[13],
labels: x[5]
});
}
return parsed;
}
api.get.visible_emails = function() {
var page = api.get.current_page();
var url = window.location.origin + window.location.pathname + '?ui=2&ik=' + api.tracker.ik+'&rid=' + api.tracker.rid + '&view=tl&start=0&num=120&rt=1';
if(page.indexOf('label/') == 0) {
url += '&cat=' + page.split('/')[1] +'&search=cat';
} else if(page.indexOf('category/') == 0) {
if(page.indexOf('forums') != -1) {
cat_label = 'group';
} else if(page.indexOf('updates') != -1) {
cat_label = 'notification';
} else if(page.indexOf('promotion') != -1) {
cat_label = 'promo';
} else if(page.indexOf('social') != -1) {
cat_label = 'social';
}
url += '&cat=^smartlabel_' + cat_label +'&search=category';
} else if(page.indexOf('search/') == 0) {
url += '&qs=true&q=' + page.split('/')[1] +'&search=query';
} else {
url += '&search=' + page;
}
var get_data = api.tools.make_request(url);
get_data = get_data.substring(get_data.indexOf('['), get_data.length);
get_data = 'api.tracker.view_data = ' + get_data;
eval(get_data)
var emails = [];
for(i in api.tracker.view_data) {
var cdata = api.tools.parse_view_data(api.tracker.view_data[i]);
if(cdata.length > 0) {
$.merge(emails, cdata);
}
}
return emails;
}
api.get.current_page = function() {
var hash = window.location.hash.split('#').pop();
var pages = ['sent', 'inbox', 'starred', 'drafts', 'imp', 'chats', 'all', 'spam', 'trash'];
var page = null;
if($.inArray(hash, pages) > -1) {
page = hash;
}
if(hash.indexOf('label/') == 0 || hash.indexOf('category/') == 0 || hash.indexOf('search/') == 0) {
if(hash.split('/').length < 3) {
page = hash;
}
}
return page;
}
api.tools.parse_email_data = function(email_data) {
var data = {};
var threads = {}
for(i in email_data) {
var x = email_data[i];
if(x[0] == 'cs') {
data.first_email = x[1];
data.last_email = x[2];
data.total_emails = x[3];
data.total_threads = x[8];
data.people_involved = x[15];
data.subject = x[23];
}
if(x[0] == 'ms') {
if(data.threads == undefined) {
data.threads = {};
}
data.threads[x[1]] = {};
data.threads[x[1]].reply_to_id = x[2];
data.threads[x[1]].from = x[5];
data.threads[x[1]].from_email = x[6];
data.threads[x[1]].timestamp = x[7];
data.threads[x[1]].datetime = x[24];
data.threads[x[1]].content_plain = x[8];
data.threads[x[1]].subject = x[12];
data.threads[x[1]].content_html = (x[13] != undefined) ? x[13][6] : x[8];
data.threads[x[1]].to = (x[13] != undefined) ? x[13][1] : [];
data.threads[x[1]].cc = (x[13] != undefined) ? x[13][2] : [];
data.threads[x[1]].bcc = (x[13] != undefined) ? x[13][3] : [];
}
}
return data;
}
api.get.email_data = function(email_id) {
if(api.check.is_inside_email() && email_id == undefined) {
email_id = api.get.email_id();
}
if(email_id != undefined) {
var url = window.location.origin + window.location.pathname + '?ui=2&ik=' + api.tracker.ik + '&rid=' + api.tracker.rid + '&view=cv&th=' + email_id + '&msgs=&mb=0&rt=1&search=inbox';
var get_data = api.tools.make_request(url);
get_data = get_data.substring(get_data.indexOf('['), get_data.length);
get_data = 'var cdata = ' + get_data;
eval(get_data);
api.tracker.email_data = cdata[0];
return api.tools.parse_email_data(api.tracker.email_data);
}
return {};
}
return api;
}
var Gmail=function(){var api={get:{},observe:{},check:{},tools:{},tracker:{},dom:{}};api.version="0.2.2";api.tracker.globals=GLOBALS;api.tracker.view_data=VIEW_DATA;api.tracker.ik=api.tracker.globals[9];api.get.last_active=function(){var e=api.tracker.globals[17][15];return{time:e[1],ip:e[3],mac_address:e[9],time_relative:e[10]}};api.get.loggedin_accounts=function(){var e=api.tracker.globals[17][23];var t=[];for(i in e[1]){t.push({name:e[1][i][4],email:e[1][i][0]})}return t};api.get.user_email=function(){return api.tracker.globals[10]};api.check.is_thread=function(){var e=$(".nH .if").children(":eq(1)").children().children(":eq(1)").children();var t=api.get.email_ids();return e.length>1||t.length>1};api.dom.inbox_content=function(){return $("div[role=main]:first")};api.check.is_preview_pane=function(){var e=api.dom.inbox_content();var t=e.find("[gh=tl]");var n=false;t.each(function(){if($(this).hasClass("aia")){n=true}});return n};api.dom.inboxes=function(){var e=api.dom.inbox_content();return e.find("[gh=tl]")};api.check.is_multiple_inbox=function(){var e=api.dom.inboxes();return e.length>1};api.check.is_horizontal_split=function(){var e=api.dom.inbox_content();var t=e.find("[gh=tl]").find(".nn");return t.length==0};api.check.is_vertical_split=function(){return api.check.is_horizontal_split()==false};api.check.is_tabbed_inbox=function(){return $(".aKh").length==1};api.check.is_right_side_chat=function(){return $(".ApVoH")[0].getAttribute("aria-labelledby")==":wf"};api.check.is_google_apps_user=function(){var e=api.get.user_email();return e.indexOf("gmail.com",e.length-"gmail.com".length)==-1};api.get.storage_info=function(){var e=$(".md.mj").find("div")[0];var t=$(e).find("span")[0].innerText;var n=$(e).find("span")[1].innerText;var r=parseFloat(t.replace(/[^0-9\.]/g,""))*100/parseFloat(n.replace(/[^0-9\.]/g,""));return{used:t,total:n,percent:Math.floor(r)}};api.dom.email_subject=function(){return $("h1.ha")};api.get.email_subject=function(){var e=api.dom.email_subject();return e.find(".hP")[0].innerText};api.dom.email_body=function(){return $(".nH.hx")};api.check.is_inside_email=function(){return api.dom.email_contents().length>0};api.dom.email_contents=function(){var e=$(".ii.gt");var t=[];for(var n=0;n<e.length;n++){var r=e[n].getAttribute("class").split(" ")[2];var i=e[n].getAttribute("contenteditable");if(r!="undefined"&&r!=undefined){if(i!="true"){t.push(e[n])}}}return t};api.get.email_ids=function(){var e=api.dom.email_contents();var t=[];for(var n=0;n<e.length;n++){var r=e[n].getAttribute("class").split(" ")[2];var i=e[n].getAttribute("contenteditable");if(r!="undefined"&&r!=undefined){if(i!="true"){t.push(r)}}}return t};api.get.email_id=function(){var e=null;if(api.check.is_inside_email()){if(api.check.is_preview_pane()){var t=api.get.email_ids();e=t[0].substring(1,t[0].length)}else{e=window.location.hash.split("/").pop().replace(/#/,"").split("?")[0]}}return e};api.check.is_priority_inbox=function(){return $(".qh").length>0};api.check.is_rapportive_installed=function(){return $("#rapportive-sidebar").length==1};api.check.is_streak_installed=function(){return $("[id^='bentoBox'],[id*=' bentoBox'],[class*=' bentoBox'],[class*='bentoBox']").length>0};api.check.is_anydo_installed=function(){return $("[id^='anydo'],[id*=' anydo'],[class*=' anydo'],[class*='anydo']").length>0};api.check.is_boomerang_installed=function(){return $("[id^='b4g_'],[id*=' b4g_'],[class*=' b4g_'],[class*='b4g_']").length>0};api.check.is_xobini_installed=function(){return $("#xobni_frame").length>0};api.check.is_signal_installed=function(){return $("[id^='Signal'],[id*=' Signal'],[class*=' signal'],[class*='signal']").length>0};api.dom.get_left_sidebar_links=function(){return $("div[role=navigation] [title]")};api.dom.search_bar=function(){return $("[gh=sb]")};api.get.search_query=function(){var e=api.dom.search_bar();return e.find("input")[0].value};api.get.unread_inbox_emails=function(){var e=$("div[role=navigation]").find("[title*='Inbox']");if(e.length>0){if(e[0].innerText.indexOf("(")!=-1){return parseInt(e[0].innerText.replace(/[^0-9]/g,""))}}return 0};api.get.unread_draft_emails=function(){var e=$("div[role=navigation]").find("[title*='Drafts']");if(e.length>0){if(e[0].innerText.indexOf("(")!=-1){return parseInt(e[0].innerText.replace(/[^0-9]/g,""))}}return 0};api.get.unread_spam_emails=function(){var e=$("div[role=navigation]").find("[title*='Spam']");if(e.length>0){if(e[0].innerText.indexOf("(")!=-1){return parseInt(e[0].innerText.replace(/[^0-9]/g,""))}}return 0};api.get.unread_forum_emails=function(){var e=$("div[role=navigation]").find("[title*='Forums']");if(e.length>0){if(e[0].innerText.indexOf("(")!=-1){return parseInt(e[0].innerText.replace(/[^0-9]/g,""))}}return 0};api.get.unread_notification_emails=function(){var e=$("div[role=navigation]").find("[title*='Notifications']");if(e.length>0){if(e[0].innerText.indexOf("(")!=-1){return parseInt(e[0].innerText.replace(/[^0-9]/g,""))}}return 0};api.get.unread_promotion_emails=function(){var e=$("div[role=navigation]").find("[title*='Promotions']");if(e.length>0){if(e[0].innerText.indexOf("(")!=-1){return parseInt(e[0].innerText.replace(/[^0-9]/g,""))}}return 0};api.get.unread_social_emails=function(){var e=$("div[role=navigation]").find("[title*='Social Updates']");if(e.length>0){if(e[0].innerText.indexOf("(")!=-1){return parseInt(e[0].innerText.replace(/[^0-9]/g,""))}}return 0};api.get.beta=function(){var e={new_nav_bar:$("#gbz").length==0};return e};api.get.unread_emails=function(){return{inbox:api.get.unread_inbox_emails(),drafts:api.get.unread_draft_emails(),spam:api.get.unread_spam_emails(),forum:api.get.unread_forum_emails(),notifications:api.get.unread_notification_emails(),promotions:api.get.unread_promotion_emails(),social:api.get.unread_social_emails()}};api.tools.parse_url=function(e){var t=/[?&]([^=#]+)=([^&#]*)/g;var n={};var r;while(r=t.exec(e)){n[r[1]]=r[2]}return n};api.tools.deparam=function(e,t){var n=function(e,t){var n=[];for(i=0;i<e.length;i++){n.push(t(e[i]))}return n};var r=Array.isArray||function(e){return Object.prototype.toString.call(e)=="[object Array]"};var s={},o={"true":!0,"false":!1,"null":null};n(e.replace(/\+/g," ").split("&"),function(e,n){var i=e.split("="),u=decodeURIComponent(i[0]),a,f=s,l=0,c=u.split("]["),h=c.length-1;if(/\[/.test(c[0])&&/\]$/.test(c[h])){c[h]=c[h].replace(/\]$/,"");c=c.shift().split("[").concat(c);h=c.length-1}else{h=0}if(i.length===2){a=decodeURIComponent(i[1]);if(t){a=a&&!isNaN(a)?+a:a==="undefined"?undefined:o[a]!==undefined?o[a]:a}if(h){for(;l<=h;l++){u=c[l]===""?f.length:c[l];f=f[u]=l<h?f[u]||(c[l+1]&&isNaN(c[l+1])?{}:[]):a}}else{if(r(s[u])){s[u].push(a)}else if(s[u]!==undefined){s[u]=[s[u],a]}else{s[u]=a}}}else if(u){s[u]=t?undefined:""}});return s};api.tools.parse_actions=function(e){if(e.method=="POST"&&typeof e.url.act=="string"){}if(e.url.search!=undefined){}var t={add_to_tasks:"tae",archive:"rc_^i","delete":"tr",delete_forever:"dl",delete_label:"dc_",discard_draft:"dd",expand_categories:"el",filter_messages_like_these:"cffm",label:"arl",mark_as_important:"mai",mark_as_not_important:"mani",mark_as_not_spam:"us",mark_as_spam:"sp",move_label:"mt",move_to_inbox:"ib",mute:"ig",read:"rd",save_draft:"sd",send_message:"sm",show_newly_arrived_message:"mo",star:"st",unmute:"ug",unread:"ur",unstar:"xst",new_email:"new_mail",poll:"poll",refresh:"refresh",open_email:"open_email"};if(typeof e.url.ik=="string"){api.tracker.ik=e.url.ik}if(typeof e.url.rid=="string"){if(e.url.rid.indexOf("mail")!=-1){api.tracker.rid=e.url.rid}}var n=t[decodeURIComponent(e.url.act)];var r=api.tools.deparam(e.body);var i=typeof r.t=="string"?[r.t]:r.t;var s=null;switch(n){case"ur":var s=[i,e.url,e.body];break;case"rd":var s=[i,e.url,e.body];break;case"tr":var s=[i,e.url,e.body];break;case"sp":var s=[i,e.url,e.body];break;case"us":var s=[i,e.url,e.body];break;case"arl":var s=[i,e.url,e.body,e.url.acn];break;case"ib":var s=[i,e.url,e.body];break;case"dl":var s=[i,e.url,e.body];break;case"st":var s=[i,e.url,e.body];break;case"xst":var s=[i,e.url,e.body];break;case"mai":var s=[i,e.url,e.body];break;case"mani":var s=[i,e.url,e.body];break;case"ig":var s=[i,e.url,e.body];break;case"ug":var s=[i,e.url,e.body];break;case"sd":var s=[i,e.url,r];break;case"dd":var s=[i,e.url,e.body];break;case"mt":var s=[i,e.url,e.body];break;case"tae":var s=[e.url,e.body,r];break;case"cffm":var s=[i,e.url,e.body];break;case"rc_^i":var s=[i,e.url,e.body];break;case"sm":var s=[e.url,e.body,r];break;case"el":var s=[e.url,e.body,r.ex=="1"];break}if(typeof e.url._reqid=="string"&&typeof e.url.th=="string"){var s=[e.url.th,e.url,e.body];if("new_email"in api.tracker.watchdog){api.tracker.watchdog["new_email"].apply(undefined,s)}}if((e.url.view=="cv"||e.url.view=="ad")&&typeof e.url.th=="string"&&typeof e.url.search=="string"){var s=[e.url.th,e.url,e.body];if("open_email"in api.tracker.watchdog){api.tracker.watchdog["open_email"].apply(undefined,s)}}if(typeof e.url.SID=="string"&&typeof e.url.zx=="string"&&e.body.indexOf("req0_")!=-1){api.tracker.SID=e.url.SID;var s=[e.url,e.body,r];if("poll"in api.tracker.watchdog){api.tracker.watchdog["poll"].apply(undefined,s)}}if(typeof e.url.ik=="string"&&typeof e.url.search=="string"&&e.body.length==0&&typeof e.url._reqid=="string"){var s=[e.url,e.body,r];if("refresh"in api.tracker.watchdog){api.tracker.watchdog["refresh"].apply(undefined,s)}}if(s!=null){if(n in api.tracker.watchdog){api.tracker.watchdog[n].apply(undefined,s)}}};api.tools.parse_requests=function(e){e.url_raw=e.url;e.url=api.tools.parse_url(e.url);if(typeof api.tracker.events!="object"&&typeof api.tracker.actions!="object"){api.tracker.events=[];api.tracker.actions=[]}api.tracker.events.unshift(e);api.tools.parse_actions(e);if(e.method=="POST"&&typeof e.url.act=="string"){api.tracker.actions.unshift(e)}if(api.tracker.events.length>50){api.tracker.events.pop()}if(api.tracker.actions.length>10){api.tracker.actions.pop()}};api.tools.xhr_watcher=function(){var e=this;if(!api.tracker.xhr_init){var t=top.document.getElementById("js_frame").contentDocument.defaultView;api.tracker.xhr_init=true;api.tracker.xhr_open=t.XMLHttpRequest.prototype.open;api.tracker.xhr_send=t.XMLHttpRequest.prototype.send;t.XMLHttpRequest.prototype._gjs_open=t.XMLHttpRequest.prototype.open;t.XMLHttpRequest.prototype.open=function(e,t,n,r,i){var s=this._gjs_open.apply(this,arguments);this.xhrParams={method:e.toString(),url:t.toString()};return s};t.XMLHttpRequest.prototype._gjs_send=t.XMLHttpRequest.prototype.send;t.XMLHttpRequest.prototype.send=function(e){var t=this._gjs_send.apply(this,arguments);if(this.xhrParams){this.xhrParams.body=e;api.tools.parse_requests(this.xhrParams)}return t}}};api.observe.http_requests=function(){return api.tracker.events};api.observe.actions=function(){return api.tracker.actions};api.observe.on=function(e,t){if(typeof api.tracker.watchdog!="object"){api.tracker.watchdog={}}if(!api.tracker.xhr_init){api.tools.xhr_watcher()}api.tracker.watchdog[e]=t};api.observe.off=function(e){if(e){if(e in self.tracker.watchdog){delete self.tracker.watchdog[e]}}else{var t=top.document.getElementById("js_frame").contentDocument.defaultView;t.XMLHttpRequest.prototype.open=api.tracker.xhr_open;t.XMLHttpRequest.prototype.send=api.tracker.xhr_send;api.tracker.xhr_init=false}};api.tools.make_request=function(e,t){var t=typeof t==undefined||typeof t==null?"GET":t;var n=$.ajax({type:t,url:encodeURI(e),async:false});return n.responseText};api.tools.parse_view_data=function(e){var t=[];var n=[];for(var r=0;r<e.length;r++){if(e[r][0]=="tb"){for(var i=0;i<e[r][2].length;i++){n.push(e[r][2][i])}}}for(var s=0;s<n.length;s++){var o=n[s];var u={};t.push({id:o[0],title:o[9],excerpt:o[10],time:o[15],sender:o[28],attachment:o[13],labels:o[5]})}return t};api.get.visible_emails=function(){var page=api.get.current_page();var url=window.location.origin+window.location.pathname+"?ui=2&ik="+api.tracker.ik+"&rid="+api.tracker.rid+"&view=tl&start=0&num=120&rt=1";if(page.indexOf("label/")==0){url+="&cat="+page.split("/")[1]+"&search=cat"}else if(page.indexOf("category/")==0){if(page.indexOf("forums")!=-1){cat_label="group"}else if(page.indexOf("updates")!=-1){cat_label="notification"}else if(page.indexOf("promotion")!=-1){cat_label="promo"}else if(page.indexOf("social")!=-1){cat_label="social"}url+="&cat=^smartlabel_"+cat_label+"&search=category"}else if(page.indexOf("search/")==0){url+="&qs=true&q="+page.split("/")[1]+"&search=query"}else{url+="&search="+page}var get_data=api.tools.make_request(url);get_data=get_data.substring(get_data.indexOf("["),get_data.length);get_data="api.tracker.view_data = "+get_data;eval(get_data);var emails=[];for(i in api.tracker.view_data){var cdata=api.tools.parse_view_data(api.tracker.view_data[i]);if(cdata.length>0){$.merge(emails,cdata)}}return emails};api.get.current_page=function(){var e=window.location.hash.split("#").pop();var t=["sent","inbox","starred","drafts","imp","chats","all","spam","trash"];var n=null;if($.inArray(e,t)>-1){n=e}if(e.indexOf("label/")==0||e.indexOf("category/")==0||e.indexOf("search/")==0){n=e}return n};api.tools.parse_email_data=function(e){var t={};var n={};for(i in e){var r=e[i];if(r[0]=="cs"){t.first_email=r[1];t.last_email=r[2];t.total_emails=r[3];t.total_threads=r[8];t.people_involved=r[15];t.subject=r[23]}if(r[0]=="ms"){if(t.threads==undefined){t.threads={}}t.threads[r[1]]={};t.threads[r[1]].reply_to_id=r[2];t.threads[r[1]].from=r[5];t.threads[r[1]].from_email=r[6];t.threads[r[1]].timestamp=r[7];t.threads[r[1]].datetime=r[24];t.threads[r[1]].content_plain=r[8];t.threads[r[1]].subject=r[12];t.threads[r[1]].content_html=r[13]!=undefined?r[13][6]:r[8]}}return t};api.get.email_data=function(){if(api.check.is_inside_email()){var url=window.location.origin+window.location.pathname+"?ui=2&ik="+api.tracker.ik+"&rid="+api.tracker.rid+"&view=cv&th="+api.get.email_id()+"&msgs=&mb=0&rt=1&search=inbox";var get_data=api.tools.make_request(url);get_data=get_data.substring(get_data.indexOf("["),get_data.length);get_data="var cdata = "+get_data;eval(get_data);api.tracker.email_data=cdata[0];return api.tools.parse_email_data(api.tracker.email_data)}return{}};return api}
#!/usr/bin/env python
import smtplib
import imaplib
import getpass
import email
import pickle
import base64
import os
from email.MIMEMultipart import MIMEMultipart
from email.Utils import COMMASPACE
from email.MIMEBase import MIMEBase
from email.parser import Parser
from email.MIMEImage import MIMEImage
from email.MIMEText import MIMEText
from email.MIMEAudio import MIMEAudio
import mimetypes
def get_int(string=''):
while True:
try:
n=int(raw_input(string))
break
except ValueError:
print 'Enter int'
return n
def send_mail(user,server):
fromaddr = raw_input('Send mail by the name of: ')
tolist = raw_input('To: ').split()
sub = raw_input('Subject: ')
msg = email.MIMEMultipart.MIMEMultipart()
msg['From'] = fromaddr
msg['To'] = email.Utils.COMMASPACE.join(tolist)
msg['Subject'] = sub
msg.attach(MIMEText(raw_input('Body: ')))
msg.attach(MIMEText('\n\n\nsent via python', 'plain'))
n=42
while n != 0:
n = get_int('1. Attach\n0. Send\nChoose an option: ')
if n==1:
msg = attach_files(msg)
elif n==0:
server.sendmail(user,tolist,msg.as_string())
print 'sent'
return
def attach_files(msg):
filename = raw_input('File name: ')
try:
f = open(filename,'rb')
except IOError:
print 'Attachment not found'
return msg
ctype, encoding = mimetypes.guess_type(filename)
if ctype is None or encoding is not None:
ctype = 'application/octet-stream'
maintype, subtype = ctype.split('/', 1)
if maintype == 'text':
part = MIMEText(f.read(), _subtype=subtype)
elif maintype == 'image':
part = MIMEImage(f.read(), _subtype=subtype)
elif maintype == 'audio':
part = MIMEAudio(f.read(), _subtype=subtype)
else:
part = MIMEBase(maintype, subtype)
msg.set_payload(f.read())
part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(filename))
msg.attach(part)
f.close()
return msg
def get_mail(mail):
MailboxList=[]
status, mailbox_list = mail.list()
for i in range(len(mailbox_list)):
MailboxList.append(mailbox_list[i].split('"')[-2])
print MailboxList[i]
mailbox = raw_input('Enter the name of the mailbox: ')
if mailbox in MailboxList:
mail.select(mailbox)
mail = get_unseen(mail)
# mail.logout()
return
def get_unseen(mail):
result, data = mail.uid('search', None, 'UNSEEN')
uid_list = data[0].split()
print len(uid_list), 'Unseen emails.'
get_email(uid_list,mail)
return mail
def get_email(uid_list,mail):
for i in range(len(uid_list)):
email_uid = uid_list[i]
res, dat = mail.uid('fetch', email_uid, '(RFC822)')
raw_email = dat[0][1]
msg = email.message_from_string(raw_email)
get_email_info(i+1,email_uid,msg)
return
def get_email_info(i,email_uid,msg):
print ''
print 'New email:\n'
print i,'UID:', email_uid, 'Sender:', email.utils.parseaddr(msg['From'])[0],email.utils.parseaddr(msg['From'])[1]
print 'Subjct:',msg['Subject']
print 'Message: '
print get_body(msg)
attach_list = get_attach_list(msg)
print len(attach_list),'Attachments:',attach_list
n = get_int('1. Download All Attachments\n0. Exit\nChoose an option: ')
if n==1:
get_attach(msg)
return
def get_body(msg):
for part in msg.walk():
content_type = part.get_content_type()
if content_type == 'text/plain' or content_type =='text/html':
payload = part.get_payload()
if payload:
print payload
return
def get_attach_list(msg):
attach_list=[]
for part in msg.walk():
filename = part.get_filename()
if filename:
attach_list.append(filename)
return attach_list
def get_attach(msg):
for part in msg.walk():
filename = part.get_filename()
if filename:
fp = open('/home/jay/Downloads/'+filename,'wb')
fp.write(part.get_payload(decode=True))
fp.close()
return
def main():
user = raw_input('Username: ')
passw = base64.b64encode(getpass.getpass())
smtp_host = 'smtp.gmail.com'
smtp_port = 587
server = smtplib.SMTP()
server.connect(smtp_host,smtp_port)
server.ehlo()
server.starttls()
server.login(user,base64.b64decode(passw))
imap_host = 'imap.gmail.com'
mail = imaplib.IMAP4_SSL(imap_host)
mail.login(user,base64.b64decode(passw))
n=42
while n != 0:
n = get_int('1. Send email\n2. Get email\n0. Exit\nChoose an option: ')
if n==1:
send_mail(user,server)
elif n==2:
get_mail(mail)
elif n==0:
server.quit()
mail.logout()
return
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment