Я скромный аналитик инфраструктуры / информации c, который старается работать умно и интересуется миром python! В настоящее время я запускаю сценарий python, чтобы прочитать старую базу данных файлов почты postfix, проанализировать некоторые поля и вставить их в базу данных SQL Server для индексации и быстрого поиска.
Однако после запуска финальной версии версия скрипта я наткнулся на кучу файлов, которые, казалось, были "повреждены" в процессе, таким образом, что некоторые файлы, похоже, имеют свое содержимое, перезаписанное кусками других почтовых файлов .
Любые идеи относительно того, почему это происходит?
Чтобы помочь, следующие подробности о скрипте:
Он устанавливает несколько переменных, например путь к папке, дата, время и учетные данные базы данных. Затем я определяю функцию для анализа данных из электронных писем, а другую - для преобразования файлов электронной почты из LATIN-1 / ISO-8859 в UTF-8.
Основная часть кода - al oop, в котором перечислены все файлы в данной папке и для каждого из перечисленных файлов проверяется, является ли это файлом электронной почты или обычным файлом.
- Если это файл электронной почты, он проверяет кодировку.
- Если это UTF-8, он запускает функцию синтаксического анализа и вставляет тада в базу данных. Если это файл LATIN-1, он преобразуется в UTF-8 и затем запускает функцию синтаксического анализа.
- Если это не файл электронной почты, он переходит к следующему файлу.
Основная часть скрипта выглядит следующим образом:
#####################################
#########Start of main loop#########
#####################################
for file in os.listdir(folder_path):
countertotal += 1
date_time = strftime("%Y-%m-%d %H:%M:%S", localtime())
###Detects file type###
file_path = str(folder_path)+"/"+file
p1 = subprocess.Popen(["file", file_path], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["awk", '{print $2}'], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close()
file_type = p2.communicate()[0].rstrip()
###Detects file format/encoding####
file_path = str(folder_path)+"/"+file
p1 = subprocess.Popen(["file", file_path], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["awk", '{print $4}'], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close()
file_format = p2.communicate()[0].rstrip()
###Checks if the file is an email and acts depending on it´s encoding####
if (file_type.decode('utf-8') == "SMTP") or (file_type.decode('utf-8') != "SMTP" and re.match('([0-9]+)\.(.*)\.(.*)', str(file))):
if (file_format.decode('utf-8') == 'ASCII' or file_format.decode('utf-8') == 'UTF-8'):
try:
ProcessEmail(file_path)
counter += 1
except:
counterb +=1
ex = sys.exc_info()[0]
tb = textwrap.fill(traceback.format_exc(), 1000)
print ("[ERRO]","[",date_time,"]: ","File: ", file, file=open(log_file_name, "a"))
print ("[ERRO]","[",date_time,"]: ","File format: ", file_format, file=open(log_file_name, "a"))
print ("[ERRO]","[",date_time,"]: ","Error type: ",ex, file=open(log_file_name, "a"))
print ("[ERRO]","[",date_time,"]: ","Traceback: ", tb, file=open(log_file_name, "a"))
pass
elif (file_format.decode('utf-8') == 'ISO-8859'):
try:
ConvertEmailIso(file_path)
ProcessEmail(file_path)
print ("[INFO]","[",date_time,"]: ", file,"-", file_format.decode('utf-8'), "converted to UTF-8",file=open(log_file_name, "a"))
counter += 1
counterd += 1
except:
counterb +=1
ex = sys.exc_info()[0]
tb = textwrap.fill(traceback.format_exc(), 1000)
print ("[ERRO]","[",date_time,"]: ","File: ", file, file=open(log_file_name, "a"))
print ("[ERRO]","[",date_time,"]: ","File format: ", file_format, file=open(log_file_name, "a"))
print ("[ERRO]","[",date_time,"]: ","Error type: ",ex, file=open(log_file_name, "a"))
print ("[ERRO]","[",date_time,"]: ","Traceback: ", tb, file=open(log_file_name, "a"))
pass
else:
print ("[INFO]","[",date_time,"]: ", file, "Is not an SMTP file", file=open(log_file_name, "a"))
counterc += 1
####################################
##########End of main loop##########
####################################
Определены следующие функции:
############################################################################################
###Function that parses data from mail files of SMTP and ASCII format and UTF-8 encoding ##
############################################################################################
def ProcessEmail(file_path):
h1 = subprocess.Popen(["md5sum", file_path], stdout=subprocess.PIPE)
h2 = subprocess.Popen(["awk", '{print $1}'], stdin=h1.stdout, stdout=subprocess.PIPE)
h1.stdout.close()
hash_key = h2.communicate()[0].decode('utf-8')
with open(file_path, 'rb') as fp:
headers = BytesParser(policy=default).parse(fp)
content = fp.read()
new_format = "%Y-%m-%d %H:%M:%S"
original_format = "%d %b %Y %H:%M:%S %z"
subject_truncated = format(headers['subject'])[:200]
try:
original_date = str(format(headers['Date']))[5:31]
converted_date = datetime.datetime.strptime(original_date, original_format).strftime(new_format)
except:
alternate_date = re.findall('\d\d\s(?:[A-Z][a-z][a-z])\s\d{4}\s[0-9]+:[0-9]+:[0-9]+\s\-[0-9]+', open(file_path).read())[0]
converted_date = datetime.datetime.strptime(alternate_date, original_format).strftime(new_format)
cursorprod.execute("insert into MAIL_AUDIT.dbo.mail_index (mail_hash,mail_to,mail_from,mail_subject,mail_date,mail_path) values (?,?,?,?,?,?)", hash_key, format(headers['to'])[0:500], format(headers['from'])[0:500], subject_truncated, converted_date, file_path)
connprod.commit()
############################################################
#############################################################
###Converts the email file from ISO-8891/LATIN-1 to UTF-8###
#############################################################
def ConvertEmailIso(file_path):
with io.open(file_path, 'r', encoding='latin-1') as f:
text = f.read()
with io.open(file_path, 'w', encoding='utf8') as f:
f.write(text)
Я записываю некоторую информацию, включая обнаруженные ошибки. В журнале я смог увидеть ошибки, в основном связанные с функцией синтаксического анализа + вставки (скрипт не может вставить в базу данных, потому что нет даты, проанализированной для поврежденных писем). Скрипт, оба почтовых файла и журнал находятся по ссылке. ниже:
https://github.com/armandelli/Python_bugs/tree/master/corrupted_files
Большое спасибо!