前回pythonでhtmlを作るプログラムを作成したが、inputとなる添付画像と本文は手作業でパソコンにメールからダウンロードする。

時間にすれば数分だが、せっかくなのでこの作業もプログラムにするのは出来ないだろうかと思った。

outlookメールにpythonでアプローチできれば応用範囲が広がる。

調べると確かにpythonを使ってoutlookのメール処理の事例やガイドが沢山載っている。copy&pasteで作ってみてもどうもうまく行かない。それぞれ環境が微妙に異なるか、上級者が初歩的なところを省略しているものもあるようだ。

1日かがりで何とか出来たので掲載しておく。

その後メール読み込みとhtml作成をまとめて1つのpythonにした。

win32com(Microsoft extention)モジュールのインストール outlookやexcelの操作が出来る
参考):MicroSoft Doc.

プログラム仕様など

python code


# -----------------------------------------------------------------------------------------------------------------
# html generater for nagano art
# 1). read outlook mail 
#     input :
#         長野美術館 folder in outlook   
#     output :
#         text_in.txt : text file - first line must be title like 美術館訪問記 - 442 ルーヴル・ランス美術館 (ref only)
#         img_in foder : attached file for save (添付 画像)
#
# 2). build html 
#     input :
#           img_in      : image file folder in same directry
#           text/text_1.txt : html code top 
#           text/text_2.txt : html code bottom
#      output :
#           nagano_art_' + title_n + '.html'
# -----------------------------------------------------------------------------------------------------------------
# import module
import os      # os interface
import win32com.client   # windows extention 
import datetime  # date time 
import shutil  # file 操作
import re       # get number 
import cv2     # get img size
from natsort import natsorted  # natural sort 
# ------------------------------------------------------------------------------
# 1).  read outlook mail
# ------------------------------------------------------------------------------
# ----- get today ymd
dt_now = datetime.datetime.now()
dt = dt_now.strftime('%Y-%m-%d') # 2020-07-10 
# dt = '2020-07-10'        
print('date: ', dt)
# os.system('PAUSE')
# outlook file 
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
root_folder = outlook.Folders.Item(3)  # target account root folder in outlook same as mail address
print('root folder:' , root_folder)
# target folder name
target_folder = root_folder.Folders['長野美術館']
# --- attached (添付)  file save folder path 
img_in = 'img_in' # image file
img_in_path = os.getcwd() + '\\' + img_in   # get img パス 
if (os.path.exists(img_in_path)):   # delete if exists
     shutil.rmtree(img_in_path)
os.mkdir(img_in_path )                # make direcrty(folder)
# --- mail text path
text_out = 'text_in.txt'
# --- get mail item 
mails =target_folder.Items     # get mail item
print(type(mails))  # <class 'win32com.client.CDispatch'>
for mail in mails:
     print("-----------------")
     print("件名: " ,mail.subject)
     print('差出人: ' ,mail.sendername)
     print("受信日時: ", mail.receivedtime)
     mail_date = str(mail.receivedtime)
#    print("本文: ", mail.body)
# ----------------------------------------------------------------
#    get mail received today  
#    save attached file
#    write text into file (ref only)
# -----------------------------------------------------------------
     if dt in mail_date:                # today's  mail ?
          with open(text_out , 'w' , encoding = 'utf-8') as f_w:
               wlines = mail.subject + '\n' 
               f_w.write(wlines)        # 1'st line subject 
          with open(text_out , 'a' , encoding = 'utf-8' , newline = '' ) as f_w:
               wlines = mail.body
               f_w.write(wlines)
          # ---- get attached file and save 
          attachments = mail.Attachments      # 添付files 
          if mail.attachments.count != 0:     # 添付 あり
               for attachment in mail.attachments:
                   img_save = img_in_path + '/' + str(attachment)
                   attachment.SaveASFile(img_save)
# ------------------------------------------------------------------------------
# 2).build html 
# ------------------------------------------------------------------------------
# --- input img file
img_in_folder = 'img_in'
# --- title name default
title_in = '美術館訪問記 - xxx yyyy'
# --- predifined text top and bottom
textp_in_1 = 'text/text_1.txt'
textp_in_2 = 'text/text_2.txt'
# --- output html folder    
path_html = 'html'
# --- name of out html 
name_outh_html = 'nagano_art_'
# --- html tag for src img 
tag_1 = '<div id="photo2">'
tag_1_2 = '<div id="photo1">'      # small wide if portrait
tag_1_3 = '<div id="photo3">'      # more landscape 
tag_2 = '<a href="javascript:;" onclick="OPEN1(\''
tag_3 = '\')">'
tag_4 = '<img src="'
tag_5 = '"></img></a><p>'
tag_6 = '"></img><p>'
tag_7 = '</p></div>'
#--- img file out folder in html 
o_file = 'img12' 
# ------------------------------------------------------------------------
# get title from mail subject 
# ------------------------------------------------------------------------
title_in = mail.subject.replace('\u3000',' ').replace('-','- ')    # 全角スペース -> 半角   美術館訪問記 - 443 リール美術館
title_n = re.sub("\\D", "", title_in )    # 数字を取り出す 訪問記no 443
path_html = path_html + '/' + name_outh_html + title_n + '.html'   # folder , html name
# ------------------------------------------------------------------------
#   copy top html line 
# ------------------------------------------------------------------------
with open(textp_in_1, 'r', encoding = 'utf-8') as f_text , open(path_html, 'w', encoding = 'utf-8') as f_w:
     for rline in f_text:
          if '<title>' in rline:
               rline = '<title>' + title_in + '</title>' + '\n'
          if '<h2>' in rline:
               rline = '<h2><span id="spand">' + title_in + '</span></h2>' + '\n'
          wline =rline
          f_w.write(wline)
          print(wline)
# ------------------------------------------------------------------------
#   read img file name from img folder , sort by name 
# ------------------------------------------------------------------------
img_files_ins = os.listdir(img_in_path)
img_files = natsorted(img_files_ins)
print(img_files)                 # img_files = [2020 7 3 1.jpg , 2020 7 3 2.jpg , ........]   
# ------------------------------------------------------------------------
#   read text file  from mail.body 本文読み込み
# ------------------------------------------------------------------------
line_ins = mail.body.splitlines()  # list 
line_ins = [i.strip() for i in line_ins]   # remove new line code
# ------------------------------------------------------------------------
#   get 添付 n :  ex) 添付1:美術館.... , 添付2:        
# ------------------------------------------------------------------------
line_tempus = [p for p in line_ins if '添付' in p and ':' in p ]
# ------------------------------------------------------------------------
#  add 改行 after '作'   , ブランク削除
# ------------------------------------------------------------------------
line_tempus = [p.replace('作','作<br>') . replace(' ',' ') for p in line_tempus]
# ------------------------------------------------------------------------
#  write img tag with 添付: コメント in html
# <div id="photo1"><a href="javascript:;" onclick="OPEN1('img12/2020 7 3 1.jpg')">
#    <img src="img12/2020 7 3 1.jpg"></img></a><p>添付1:美術館までの無料バス</p></div>
#    check portrait (縦長)  or Landscape(横長)
# ------------------------------------------------------------------------
with open(path_html , 'a' , encoding = 'utf-8') as f_w:
     i = 1
     for i_name in img_files:
          pf = img_in_folder + '/' + i_name   # get img path name   # img12/2020 7 3 1.jpg
          print(pf)
          im = cv2.imread(pf)
          im_pf = im.shape               # get hight , width , color 
          tag_1_0 = tag_1                # default 
          if im_pf[0] > im_pf[1] :      # portrait ?  
             tag_1_0 = tag_1_2          # small width
          if im_pf[1] / im_pf[0] > 1.5 :
             tag_1_0 = tag_1_3           # more landscape  
          wline = '\n' + tag_1_0 + tag_2 + o_file + '/' + i_name + tag_3 + tag_4 + o_file + '/' + i_name + tag_5 + line_tempus[i-1] + tag_7
          f_w.write(wline)
          print(wline)
          i +=  1
# ------------------------------------------------------------------------
# ---- read text and write html with insert <p>...</p> 行替え
# ------------------------------------------------------------------------
with open(path_html , 'a' , encoding = 'utf-8') as f_w:
     in_text = '\n' + '</div>' + '\n' + '<div id="divtext">' + '\n' + '<p>'   # text start
     f_w.write(in_text)
     i = 1
     for in_text in line_ins:
          if '添付' in in_text and ':' in in_text:     # end 
                  break
          if i == 1 and '美術館訪問記' in in_text :   # discard first line 
                   continue
          if in_text == '' : 
             in_text = '\n' + '</p>' + '\n' + in_text + '<p>'
          f_w.write(in_text)
          i += 1
     in_text = '</p>' + '\n' + '</div>' + '\n'      # text last 
     f_w.write(in_text)
# ------------------------------------------------------------------------
# ---- copy html part2 , change next html name 
# ------------------------------------------------------------------------
with open(textp_in_2, 'r' , encoding = 'utf-8') as f_text , open(path_html , 'a' , encoding = 'utf-8') as f_w:
     t = int(title_n)  + 1
     title_n = str(t)
     for wline in f_text:
          if '<div id="divnextpage">' in wline:
              wline = '<div id="divnextpage"><a href="nagano_art_' + title_n + '.html"><p>美術館訪問記 No.' + title_n +  'はこちら</p></a></div>' + '\n'
          f_w.write(wline)
print('-------end --------')
#--- end


outlook mail 操作 メモ

ターゲットのfolderまでたどり付くのに手間取ったのでメモしておく

outlookのfolder 構造
 
 abc@def.ne.jp   root folder 
   削除済みアイテム
   受信トレイ
   送信トレイ
   送信済みアイテム
   予定表
   連絡先
   ........
   長野美術館 (目的のfolder)
   ........
 ghi@jkl.ne.jp   root folder
   削除済みアイテム
   受信トレイ
   ........
 mno@pqr.ne.jp   root folder
   削除済みアイテム
   受信トレイ
   ........

python code (参照:MailItem プロパティ (Outlook))


# outlook 
import win32com.client
import os
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
root_folder = outlook.Folders.Item(3)   3つのアカウントの順番は不明なので 1 から記入してみた
print('root folder:',root_folder)
print(len(root_folder.Folders))
folder_name = '長野美術館'
for i in root_folder.Folders:
    print(i)
    if folder_name in str(i):
        target_folder = root_folder.Folders[folder_name]
        mails =target_folder.Items
        print(type(mails))  # 
        for mail in mails:
             print('-----------------')
             print('件名: ' ,mail.subject)
             print('送り主: ',mail.sendername)
             print('受信日時: ', mail.receivedtime)
             print('本文: ', mail.body)
        break

上記コードの出力(太字は追加コメント)


root folder: abc@def.ne.jp - outlook
20  (folder数)
削除済みアイテム
受信トレイ
送信トレイ
送信済みアイテム
予定表
連絡先
履歴
メモ
タスク
下書き
RSS フィード
スレッド アクション設定
クイック操作設定
迷惑メール
長野美術館  (目的のfolder)
<class 'win32com.client.CDispatch'>
-----------------
件名:  美術館訪問記 - 441 美術館訪問記 -441 長崎県美術館
送り主:  長野
受信日時:  2020-06-26 08:08:29+00:00
本文:  	(省略)
-----------------
件名:  美術館訪問記 - 442 ルーヴル・ランス美術館
送り主:  長野
受信日時:  2020-07-03 08:05:03+00:00
本文:  	(省略)
-----------------
.................................
>>> 




Total Today Yesterday