#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# Sends a file as email via SMTP
#
# original by osakaaa
# https://gist.github.com/osakaaa/f23d1a70c8fc58c8ca85a842e8b055d9
#
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import time
import sys
import argparse
import smtplib
from pathlib import Path
import json
from os import walk


class Sender():
	def __init__(self, config, tls=True):
		self._recepients = config['to']
		self._login = config['from']
		self._password = config['password']
		self._server_address = config['server']
		self._server = smtplib.SMTP(self._server_address)

		if tls is True:
			self._server.starttls()
		if self._password != "":
			self._server.login(self._login, self._password)


	def cook_message(self, subject, content):
		text = "fail"

		self._message = MIMEMultipart('alternative')
		self._message['Subject'] = subject
		self._message['From'] = self._login
		_part1 = MIMEText(text, 'plain')
		_part2 = MIMEText(content, 'html')				 
		self._message.attach(_part1)
		self._message.attach(_part2)

	def send(self):
		for recepient in self._recepients:
			self._message['To'] = recepient
			self._server.sendmail(self._login, recepient, self._message.as_string())
			print("[+] {} to {} was sent successfully".format(self._message['Subject'], self._message['To']))
	
	def disconnect(self):
		self._server.quit()

def populate_queue(location):
	files = []
	if Path(location).is_file():
		files.append(location)
	else:
		for (dirpath, dirnames, filenames) in walk(location):
			files.append("location"+"/"+filenames)
			break
	for file in files:
		print(file)
		try:
			with open(file, "r") as f:
				yield((file.split("/")[-1],f.read()))
		except UnicodeDecodeError:
			continue

def generate_config(config_path):
	#config = {
	#	"from":"",
	#	"password":"",
	#	"to": [],
	#	"server": "",
	#}
	#with open(config_path, "w") as f:
	#	f.write(json.dumps(config))
	with open(config_path, "w") as f:
		f.write( """{
    "from":     "",
    "to":       [ "" ],
    "server":   "",
    "password": ""
}""" )

def check_config(config_json):
	for key in ["from","password","to","server"]:
		if key not in config_json:
			print( "[-] key '%s' not in JSON config file." % key )
			return False
	return True

def parse_arguments():
	_config = None
	_parser = argparse.ArgumentParser(description="mailer sends html from single file or from folder based on provided config.\r\n \
	if config doesn't exists it gets created")
	_parser.add_argument("-c", "--config", help="Configuration file", required=True)
	_parser.add_argument("-l", "--file_location", help="Path to a file or folder with content to send")
	_args = _parser.parse_args()
	if not Path(_args.config).is_file():
		generate_config(_args.config)
		print("[+] Blank config was created. Exiting")
		sys.exit()
	else:
		_bad_config = False
		try:
			with open(_args.config) as f:	
				_config = json.load(f)
				if not check_config(_config):
					_bad_config = True
		except json.decoder.JSONDecodeError as e:
			print( "[-] JSON decode error:\n  %s" % str(e) )
			_bad_config = True   
		if _bad_config is True:
			print("[-] Bad config file. Exiting")
			sys.exit()
	print("[+] Config loaded successfully")
	print("[+] Sender's email: {}".format(_config['from']))
	print("[+] Recepient's email: {}".format(_config['to']))
	print("[+] SMTP server to use: {}".format(_config['server']))
	if _args.file_location is None:
		print("[*] File location wasn't provided. Exiting")
		sys.exit()
	if not Path(_args.file_location).is_dir() and not Path(_args.file_location).exists():
		print("[-] Bad folder specified. Exiting")
		sys.exit()
	print("[+] Files location: {}".format(_args.file_location))
	return (_config, _args.file_location)

if __name__ == "__main__":
	config, location = parse_arguments()
	sender = Sender(config)

	for content in populate_queue(location):
		sender.cook_message(content[0],content[1])
		sender.send()
	sender.disconnect()

