LINUX.ORG.RU

История изменений

Исправление noname_user, (текущая версия) :

собственно выложу, что получилось, код мб и не очень, но другим думаю поможет:

# -*- coding: utf-8 -*-

from email.parser import BytesParser, Parser
from email.policy import default
import mailbox
import MySQLdb as mdb
import quopri
import string
import uuid
import base64
import re
import time

con = mdb.connect('localhost', '', '', '', use_unicode=True, charset="utf8");

def encoded_words_to_text(encoded_words):
	encoded_word_regex = r'=\?{1}(.+)\?{1}([B|Q])\?{1}(.+)\?{1}='
	try:
		charset, encoding, encoded_text = re.match(encoded_word_regex, encoded_words).groups()
	except Exception as e:
		return None
	if encoding is 'B':
		byte_string = base64.b64decode(encoded_text)
	elif encoding is 'Q':
		byte_string = quopri.decodestring(encoded_text)
	return byte_string.decode(charset)

with con:
	for message in mailbox.mbox('/var/mail/mailbot'):
		attachs = list()
		headers = Parser(policy=default).parsestr(str(message))
		if message.is_multipart():
			# get body mail
			for body in message.get_payload():
				if body.get_content_type() == 'text/plain':
					bodytext = quopri.decodestring(str(message.get_payload()[1].get_payload())).decode('utf8')
				if body.get_content_type() == 'multipart/alternative':
					for body2 in body.get_payload():
						bodytext = quopri.decodestring(str(body2.get_payload())).decode('utf8')
					
		for part in message.walk():
			if part.get_content_maintype() == 'multipart': continue
			# if part.get_content_maintype() == 'text': continue
			if part.get('Content-Disposition') == 'inline': continue
			if part.get('Content-Disposition') is None: continue

			filename = part.get_filename()
			if filename != None:
				if not encoded_words_to_text(filename):
					filename=filename
				else :
					filename=encoded_words_to_text(filename)
			filename=str(uuid.uuid1())+'|'+filename
			open('/home/admin/web/***/public_html/attach/'+filename, 'wb').write(part.get_payload(decode=True))
			attachs.append(filename)

		cur = con.cursor()
		cur.execute("select id from mails where mailid = %s",(headers['Message-Id'],))
		mail = rows = cur.fetchone()
		if(mail == None):
			timestamp = int(time.time())
			cur.execute('INSERT INTO mails(`mailid`, `subject`, `to`, `from`, `body`, `time_receive`) VALUES(%s, %s, %s, %s, %s, %s)',(headers['Message-ID'], headers['subject'].encode('utf-8'), headers['to'], headers['from'], bodytext, timestamp))
			mailid = cur.lastrowid
		for at in attachs:
				cur.execute('INSERT INTO attach(`mailid`, `name`) VALUES(%s, %s)', (mailid, at))

Исходная версия noname_user, :

собственно выложу, что получилось, код мб и не очень, но другим думаю поможет:

# -*- coding: utf-8 -*-

from email.parser import BytesParser, Parser
from email.policy import default
import mailbox
import MySQLdb as mdb
import quopri
import string
import uuid
import base64
import re
import time

con = mdb.connect('localhost', '', '', '', use_unicode=True, charset="utf8");

def encoded_words_to_text(encoded_words):
	encoded_word_regex = r'=\?{1}(.+)\?{1}([B|Q])\?{1}(.+)\?{1}='
	try:
		charset, encoding, encoded_text = re.match(encoded_word_regex, encoded_words).groups()
	except Exception as e:
		return None
	if encoding is 'B':
		byte_string = base64.b64decode(encoded_text)
	elif encoding is 'Q':
		byte_string = quopri.decodestring(encoded_text)
	return byte_string.decode(charset)

with con:
	for message in mailbox.mbox('/var/mail/mailbot'):
		attachs = list()
		headers = Parser(policy=default).parsestr(str(message))
		if message.is_multipart():
			# get body mail
			for body in message.get_payload():
				if body.get_content_type() == 'text/plain':
					bodytext = quopri.decodestring(str(message.get_payload()[1].get_payload())).decode('utf8')
				if body.get_content_type() == 'multipart/alternative':
					for body2 in body.get_payload():
						bodytext = quopri.decodestring(str(body2.get_payload())).decode('utf8')
					
		for part in message.walk():
			if part.get_content_maintype() == 'multipart': continue
			# if part.get_content_maintype() == 'text': continue
			if part.get('Content-Disposition') == 'inline': continue
			if part.get('Content-Disposition') is None: continue

			filename = part.get_filename()
			if filename != None:
				if not encoded_words_to_text(filename):
					filename=filename
				else :
					filename=encoded_words_to_text(filename)
			filename=str(uuid.uuid1())+'|'+filename
			open('/home/admin/web/***/public_html/attach/'+filename, 'wb').write(part.get_payload(decode=True))
			attachs.append(filename)

		cur = con.cursor()
		cur.execute("select id from mails where mailid = %s",(headers['Message-Id'],))
		mail = rows = cur.fetchone()
		if(mail == None):
			timestamp = int(time.time())
			cur.execute('INSERT INTO mails(`mailid`, `subject`, `to`, `from`, `body`, `time_receive`) VALUES(%s, %s, %s, %s, %s, %s)',(headers['Message-ID'], headers['subject'].encode('utf-8'), headers['to'], headers['from'], bodytext, timestamp))
			mailid = cur.lastrowid
			cur.execute('SELECT `count_receive` from settings')
			counter = cur.fetchone()
			for at in attachs:
				cur.execute('INSERT INTO attach(`mailid`, `name`) VALUES(%s, %s)', (mailid, at))