回答編集履歴
5
typo fix
    
        answer	
    CHANGED
    
    | @@ -77,7 +77,7 @@ | |
| 77 77 | 
             
            ```python
         | 
| 78 78 | 
             
            with open(filepath, 'rt', encoding='Shift-JIS') as f:
         | 
| 79 79 | 
             
                content = f.read()
         | 
| 80 | 
            -
                attachment = MIMEText(content, 'comma-separated-values', | 
| 80 | 
            +
                attachment = MIMEText(content, 'comma-separated-values', 'Shift-JIS')
         | 
| 81 81 | 
             
                filename_rfc2047 = Header(filename, 'iso-2022-jp', maxlinelen=55).encode().replace('\n', '')
         | 
| 82 82 | 
             
                attachment.set_param('name', filename_rfc2047)
         | 
| 83 83 | 
             
                attachment.add_header('Content-Disposition', 'attachment', filename=filename_rfc2047)
         | 
4
Outlookの特徴に合わせて訂正
    
        answer	
    CHANGED
    
    | @@ -64,4 +64,22 @@ | |
| 64 64 |  | 
| 65 65 | 
             
            ~~`MIMEText`を構築するときも、`policy`という引数のデフォルトは`compat32`であり、行終端を`\r\n`で指定しています。`policy`を`email.policy.SMTP`にしてみましょう。~~
         | 
| 66 66 |  | 
| 67 | 
            -
            `SMTP.sendmail`は`\n`を`\r\n`に変換しますので、上記の必要がありません。
         | 
| 67 | 
            +
            `SMTP.sendmail`は`\n`を`\r\n`に変換しますので、上記の必要がありません。
         | 
| 68 | 
            +
             | 
| 69 | 
            +
            ## 追記 2
         | 
| 70 | 
            +
             | 
| 71 | 
            +
            少なくともOutlookが RFC 2047 を従ってるはずと思った僕は甘すぎたかもしれません。もっとOutlookのバーションに接近しなきゃいけなさそうです。
         | 
| 72 | 
            +
             | 
| 73 | 
            +
            数えたら、Outlookのencoded wordの一区切りの長さは54、RFC 2047の75と違っています。そして二重引用符の中に行終端がありません。この二つを訂正していきましょう。
         | 
| 74 | 
            +
             | 
| 75 | 
            +
            こうしたら残した一致してないところは`;`後の行終端だけなはずですが、どうなりますかね。とりあえず試してみてください。
         | 
| 76 | 
            +
             | 
| 77 | 
            +
            ```python
         | 
| 78 | 
            +
            with open(filepath, 'rt', encoding='Shift-JIS') as f:
         | 
| 79 | 
            +
                content = f.read()
         | 
| 80 | 
            +
                attachment = MIMEText(content, 'comma-separated-values',', 'Shift-JIS')
         | 
| 81 | 
            +
                filename_rfc2047 = Header(filename, 'iso-2022-jp', maxlinelen=55).encode().replace('\n', '')
         | 
| 82 | 
            +
                attachment.set_param('name', filename_rfc2047)
         | 
| 83 | 
            +
                attachment.add_header('Content-Disposition', 'attachment', filename=filename_rfc2047)
         | 
| 84 | 
            +
                print(attachment)
         | 
| 85 | 
            +
            ```
         | 
3
linesep について訂正
    
        answer	
    CHANGED
    
    | @@ -60,6 +60,8 @@ | |
| 60 60 |  | 
| 61 61 | 
             
            ## 追記 1
         | 
| 62 62 |  | 
| 63 | 
            -
            `Header`クラスはデフォルトで`\n`を使って行を区切りますが、それはRFCにあっていません。`linesep='\r\n'`をしてみましょう。上記のコードも訂正します。
         | 
| 63 | 
            +
            ~~`Header`クラスはデフォルトで`\n`を使って行を区切りますが、それはRFCにあっていません。`linesep='\r\n'`をしてみましょう。上記のコードも訂正します。~~
         | 
| 64 64 |  | 
| 65 | 
            -
            `MIMEText`を構築するときも、`policy`という引数のデフォルトは`compat32`であり、行終端を`\r\n`で指定しています。`policy`を`email.policy.SMTP`にしてみましょう。
         | 
| 65 | 
            +
            ~~`MIMEText`を構築するときも、`policy`という引数のデフォルトは`compat32`であり、行終端を`\r\n`で指定しています。`policy`を`email.policy.SMTP`にしてみましょう。~~
         | 
| 66 | 
            +
             | 
| 67 | 
            +
            `SMTP.sendmail`は`\n`を`\r\n`に変換しますので、上記の必要がありません。
         | 
2
linesep について追加
    
        answer	
    CHANGED
    
    | @@ -18,12 +18,12 @@ | |
| 18 18 |  | 
| 19 19 | 
             
            ```python
         | 
| 20 20 | 
             
            from email.header import Header
         | 
| 21 | 
            -
            contentType = Header('text/comma-separated-values;', header_name='Content-Type')
         | 
| 21 | 
            +
            contentType = Header('text/comma-separated-values;', header_name='Content-Type', linesep='\r\n')
         | 
| 22 22 | 
             
            contentType.append('name="')
         | 
| 23 23 | 
             
            contentType.append(filename, charset='iso-2022-jp')
         | 
| 24 24 | 
             
            contentType.append('"')
         | 
| 25 25 | 
             
            attachment['Content-Type'] = contentType
         | 
| 26 | 
            -
            contentDisp = Header('attachment;', header_name='Content-Disposition')
         | 
| 26 | 
            +
            contentDisp = Header('attachment;', header_name='Content-Disposition', linesep='\r\n')
         | 
| 27 27 | 
             
            contentDisp.append('filename="')
         | 
| 28 28 | 
             
            contentDisp.append(filename, charset='iso-2022-jp')
         | 
| 29 29 | 
             
            contentDisp.append('"')
         | 
| @@ -41,17 +41,25 @@ | |
| 41 41 | 
             
            問題文と合わせたら、`with open`のブロックはこうなります:
         | 
| 42 42 |  | 
| 43 43 | 
             
            ```python
         | 
| 44 | 
            +
            from email import policy
         | 
| 45 | 
            +
             | 
| 44 46 | 
             
            with open(filepath, 'rt', encoding='Shift-JIS') as f:
         | 
| 45 47 | 
             
                content = f.read()
         | 
| 46 | 
            -
                attachment = MIMEText(content, 'plain', 'Shift-JIS')
         | 
| 48 | 
            +
                attachment = MIMEText(content, 'plain', 'Shift-JIS', policy=policy.SMTP)
         | 
| 47 | 
            -
                contentType = Header('text/comma-separated-values;', header_name='Content-Type')
         | 
| 49 | 
            +
                contentType = Header('text/comma-separated-values;', header_name='Content-Type', linesep='\r\n')
         | 
| 48 50 | 
             
                contentType.append('name="')
         | 
| 49 51 | 
             
                contentType.append(filename, charset='iso-2022-jp')
         | 
| 50 52 | 
             
                contentType.append('"')
         | 
| 51 53 | 
             
                attachment['Content-Type'] = contentType
         | 
| 52 | 
            -
                contentDisp = Header('attachment;', header_name='Content-Disposition')
         | 
| 54 | 
            +
                contentDisp = Header('attachment;', header_name='Content-Disposition', linesep='\r\n')
         | 
| 53 55 | 
             
                contentDisp.append('filename="')
         | 
| 54 56 | 
             
                contentDisp.append(filename, charset='iso-2022-jp')
         | 
| 55 57 | 
             
                contentDisp.append('"')
         | 
| 56 58 | 
             
                attachment['Content-Disposition'] = contentDisp
         | 
| 57 | 
            -
            ```
         | 
| 59 | 
            +
            ```
         | 
| 60 | 
            +
             | 
| 61 | 
            +
            ## 追記 1
         | 
| 62 | 
            +
             | 
| 63 | 
            +
            `Header`クラスはデフォルトで`\n`を使って行を区切りますが、それはRFCにあっていません。`linesep='\r\n'`をしてみましょう。上記のコードも訂正します。
         | 
| 64 | 
            +
             | 
| 65 | 
            +
            `MIMEText`を構築するときも、`policy`という引数のデフォルトは`compat32`であり、行終端を`\r\n`で指定しています。`policy`を`email.policy.SMTP`にしてみましょう。
         | 
1
問題文と合わせるコードを追加
    
        answer	
    CHANGED
    
    | @@ -32,7 +32,26 @@ | |
| 32 32 |  | 
| 33 33 | 
             
            参考と問題を分析しただけの結果ですので、100%の把握がないけど、お役に立てたら幸いです。
         | 
| 34 34 |  | 
| 35 | 
            -
             | 
| 36 35 | 
             
            参考:
         | 
| 37 36 | 
             
            [c# - japanese email subject encoding - Stack Overflow](https://stackoverflow.com/a/492543)
         | 
| 38 | 
            -
            [The mess that is attachment filenames – Nodemailer. Blog](https://blog.nodemailer.com/2017/01/27/the-mess-that-is-attachment-filenames/)
         | 
| 37 | 
            +
            [The mess that is attachment filenames – Nodemailer. Blog](https://blog.nodemailer.com/2017/01/27/the-mess-that-is-attachment-filenames/)
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            ## 追記
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            問題文と合わせたら、`with open`のブロックはこうなります:
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            ```python
         | 
| 44 | 
            +
            with open(filepath, 'rt', encoding='Shift-JIS') as f:
         | 
| 45 | 
            +
                content = f.read()
         | 
| 46 | 
            +
                attachment = MIMEText(content, 'plain', 'Shift-JIS')
         | 
| 47 | 
            +
                contentType = Header('text/comma-separated-values;', header_name='Content-Type')
         | 
| 48 | 
            +
                contentType.append('name="')
         | 
| 49 | 
            +
                contentType.append(filename, charset='iso-2022-jp')
         | 
| 50 | 
            +
                contentType.append('"')
         | 
| 51 | 
            +
                attachment['Content-Type'] = contentType
         | 
| 52 | 
            +
                contentDisp = Header('attachment;', header_name='Content-Disposition')
         | 
| 53 | 
            +
                contentDisp.append('filename="')
         | 
| 54 | 
            +
                contentDisp.append(filename, charset='iso-2022-jp')
         | 
| 55 | 
            +
                contentDisp.append('"')
         | 
| 56 | 
            +
                attachment['Content-Disposition'] = contentDisp
         | 
| 57 | 
            +
            ```
         | 
