#! /usr/bin/env python3

import sys
import imaplib
import email
import email.header
import datetime
from textwrap import wrap # For pretty printing assistance
import json
import time
import os.path
from os.path import expanduser

WRAP_LIMIT = 80
path = "/home/kuba/.conky/gmail/last.json"

def process_mailbox(M):
    rv, data = M.search(None, "ALL")
    if rv != 'OK':
        print ("No messages found!")
        return
    numbers = data[0].split()
    ln = len(numbers)
    timestamp = str(round(time.time()))

    parsed_data = {} #Find and save last 10 emails
    parsed_data['timestamp'] = timestamp
    emails = []
    for num in numbers[ln:ln-10:-1]:
        rv, data = M.fetch(num, '(RFC822)')
        if rv != 'OK':
            print ("ERROR getting message"), num
            return
        eml = {}

        msg = email.message_from_bytes(data[0][1])
        eml.update({'subject' : decode_field(msg['Subject'])})
        eml.update({'sender'  : decode_field(msg['From'])})
        date_tuple = email.utils.parsedate_tz(msg['Date'])
        if date_tuple:
            local_date = datetime.datetime.fromtimestamp(
                email.utils.mktime_tz(date_tuple))
            eml.update({'date' : local_date.strftime("%a, %d %b %Y %H:%M:%S")})
        emails.append(eml)

    parsed_data['emails'] = emails
    with open(path, 'w') as outfile:
        json.dump(parsed_data, outfile)

def fetch_mail():
    M = imaplib.IMAP4_SSL('imap.gmail.com')

    try:
        json_data=open(expanduser('~')+'/.conky/scripts/.passwords.json')
        data = json.load(json_data)
        username=data['gmail']['username']
        password=data['gmail']['password']
        rv, data = M.login(username, password)
    except imaplib.IMAP4.error:
        print ("LOGIN FAILED!!! ")
        sys.exit(1)

    rv, data = M.select()
    if rv == 'OK':
#    print("Processing mailbox...\n")
        process_mailbox(M)
        M.close()
    else:
        print("ERROR: Unable to open mailbox ", rv)

    M.logout()

def fill(text, width):
    '''A custom method to assist in pretty printing'''
    if len(text) < width:
        return text + ' '*(width-len(text))
    else:
        return text

def decode_field(data):
        decode = email.header.decode_header(data)[0]
        if decode[1] == None or decode[1] == 'unknown-8bit':
            return str(decode[0])
        else:
            return str(decode[0], decode[1])

def print_output(data):
    timestamp = int(data['timestamp'])
    updated = time.strftime("%m/%d %H:%M", time.gmtime(timestamp))
    print ("${alignr}Updated: ${color white}%s" % updated)

    for mail in data['emails']:
        subject = mail['subject']
        sender = mail['sender']
        dte = mail['date']
        if(len(subject) > WRAP_LIMIT - 3):
            print ("${color1}%s..." % subject)
        else:
            print ("${color1}%s" % subject)

# Does file exist?
if not (os.path.isfile(path)):
    fetch_mail()
with open(path) as infile:
    data = json.load(infile)

# Is data recently fetched?
ts = int(data['timestamp'])
now = round(time.time())
if (ts + 3600 < now):
    fetch_mail()
    with open(path) as infile:
        data = json.load(infile)

# Format output
print_output(data)
