#!/usr/bin/env python3

###################################################################
# To the extent possible under law, the person who associated CC0 #
# with phlog-bot.py has waived all copyright and related or       #
# neighboring rights to phlog-bot.py.                             #
#                                                                 #
# https://creativecommons.org/publicdomain/zero/1.0/              #
###################################################################

# NO WARRANTY!!!! 
# PLEASE DON'T RUN THIS SCRIPT UNLESS YOU HAVE BACKUPS OF YOUR
# MAILFILE OR ANYTHING ELSE THIS SCRIPT TOUCHES PLEASE.

import mailbox
import json
import time
import datetime
import os

gopherdir = "/home/lro/gopher/test"
userdictionaryfile = "users.json"
mailboxf = "test-mbox"
today = datetime.date.today()
todayfmt = today.strftime("%d")
yearmonth = today.strftime("%Y")+"-"+today.strftime("%m")

def get_unread_emails(mailboxfile):
    unread = []
    if not os.path.isfile(mailboxfile):
        print("Mailboxfile doesn't exist: %s" % (mailboxfile))
        return unread
    
    mailboxfp = mailbox.mbox(mailboxfile)
    ind = 0
    for message in mailboxfp:
        flags = message.get_flags()
        if flags.find('R') == -1:
            unread.append(message)
            message.add_flag('R')
            mailboxfp[ind] = message
        ind = ind + 1

    mailboxfp.lock()
    mailboxfp.flush()
    mailboxfp.unlock()
    mailboxfp.close()
    return unread

def load_dictionary(dictfile):
    if not os.path.isfile(dictfile):
        return []
    
    usersfile = open(dictfile)
    userdictionary = json.load(usersfile)
    usersfile.close()
    return userdictionary

def get_from_lower(message):
    From = message.get_from()
    return From.split(" ")[0].lower()

def user_in_dict(email, dictionary):
    try:
        return dictionary[email]
    except KeyError:
        return False

def phlog_post_contents(email):
    return email.get_payload()

def write_phlog_post(filename, contents):
    ind = 0
    justfilenamenotpath = filename.split("/")[-1]
    while os.path.isfile(filename):
        if ind == 99:
            break

        ind += 1
        filename = filename.split(".")[0].split("_")[0]+"_"+str(ind)+".txt"
        justfilenamenotpath = filename.split("/")[-1]

    with open(filename, "w") as phlogfile:
        phlogfile.write(contents)

    return justfilenamenotpath

def add_gophermap(gophermap, filename, description):
    entry = "0%s	%s" % (description, filename)

    with open(gophermap, "r") as gfp:
        buf = gfp.readlines()

    with open(gophermap, "w") as gfp:
        for line in buf:
            if "==================================================" in line:
                line = line+"\n"+entry
            gfp.write(line)

def update_gophermap(gophermap, filename, description):
    entry = "0%s	%s" % (description, filename)

    with open(gophermap, "r") as gfp:
        buf = gfp.readlines()

    posts = 0
    for line in buf:
        if line.startswith("0"): 
            posts += 1
            if posts > 10:
                buf.remove(line)
                posts -= 1

    with open(gophermap, "w") as gfp:
        for line in buf:
            if "==================================================" in line:
                line = line+"\n"+entry
            gfp.write(line)

def create_archive_dir(phlogdir, yearmonth):
    if not os.path.isdir(phlogdir+"/"+yearmonth):
        os.mkdir(phlogdir+"/"+yearmonth)
        with open(phlogdir+"/"+yearmonth+"/gophermap", "w+") as f:
            f.write("i==================================================\n")
        with open(phlogdir+"/gophermap", "a") as f:
            f.write("\n\n1Archive of phlosts from: "+yearmonth+"	"+yearmonth)

def new_phlog_entry(message):
    email = get_from_lower(message)
    username = user_in_dict(email, userdictionary)
    if not username:
        print("User: %s not in user dictionary" % (email))
        return

    phlogtitle = message['subject']
    phlogfilename = todayfmt + ".txt"
    phlogcontents = phlog_post_contents(message)
    phlogdir = gopherdir+"/"+username

    create_archive_dir(phlogdir, yearmonth)

    phlogfilename = write_phlog_post(phlogdir+"/"+yearmonth+"/"+phlogfilename, phlogcontents)
    ymd = "<"+yearmonth+"-"+todayfmt+">"

    update_gophermap(phlogdir+"/gophermap", yearmonth+"/"+phlogfilename, phlogtitle+" "+ymd)
    add_gophermap(phlogdir+"/"+yearmonth+"/gophermap", phlogfilename, phlogtitle+" "+ymd)
    update_gophermap(gopherdir+"/gophermap", username+"/"+yearmonth+"/"+phlogfilename, username+" - "+phlogtitle+" "+ymd)
    print("Added phlog post for %s" % (username))

userdictionary = load_dictionary(userdictionaryfile)

for message in get_unread_emails(mailboxf):
    new_phlog_entry(message)