tshのblog

tshのblog

Kindle OASISにPDFドキュメントを流し込む(その6)(ソースコードをカラー化しました)

前回は、今までの一連の動作をまとめ、送信元によって動作を変えたりしました。

tsh.hatenablog.jp

今回は、コードの不自然な部分やバグを修正したりしてみます。

[asin:B07ZWCDYZG:detail] evernote.com trello.com


コードの不自然な部分を修正

各操作に名前をつける

コードをよく眺めてみるとコードに不自然な部分がありますね。

色々なツールにPDFドキュメントを流し込むのに、Evernoteのノートブック名がその実行条件になっているように読めますので、改善してみます。

まず、この「PDFを流し込む」という操作に名前をつけることにします。とりあえず「PDFを流し込む」という動作をすることから "pdfsend" あたりにしておきましょう。また、実行する条件としては「From: が条件に当てはまるかどうか」なので、名前を "check_from" くらいにしておくとすると、次のようなコードになります。

#test4-1-1 該当部分のみ抜粋
if header :contains "From" "example1.co.jp"
{
  set "pdfsend_check_from" "true";
  set "kindle_convert" "true";
  set "evernote_notebook" "テスト1";
  set "trello_assign" "exampleuser1";
}
elsif header :contains "From" "example2.co.jp"
{
  set "pdfsend_check_from" "true";
  set "evernote_notebook" "テスト2";
  set "trello_assign" "exampleuser2";
}

if string :count "eq" "${pdfsend_check_from}" "1"
{

次に、今と同様に「各ツールを実行するかどうかの条件」に名前をつけます。例えばKindleを実行するかどうかを判定するのなら "kindle_run"、といった名前に決めたとすると、次のようになります。

#test4-1-2 該当部分のみ抜粋
if header :contains "From" "example1.co.jp"
{
  set "pdfsend_check_from" "true";

  set "kindle_run" "true";
  set "kindle_convert" "true";

  set "evernote_run" "true";
  set "evernote_notebook" "テスト1";

  set "trello_run" "true";
  set "trello_assign" "exampleuser1";
}
elsif header :contains "From" "example2.co.jp"
{
  set "pdfsend_check_from" "true";

  set "kindle_run" "true";

  set "evernote_run" "true";
  set "evernote_notebook" "テスト2";

  set "trello_run" "true";
  set "trello_assign" "exampleuser2";
}

if string :count "eq" "${pdfsend_check_from}" "1"
{
  foreverypart
  {
    if header :mime :subtype "Content-Type" "pdf"
    {
      if string :count "eq" "${kindle_run}" "1"
      {
        include "send-kindle";
      }
      if string :count "eq" "${evernote_run}" "1"
      {
        include "send-evernote";
      }
      if string :count "eq" "${trello_run}" "1"
      {
        include "send-trello";
      }

コードが少々長くなってきましたので、別ファイルに切り出す事を考えます。「PDFを各アプリへ送り込む実行部分」がひとまとまりになりそうなので、名前をつけて別ファイルへ切り出します。ここでは "pdfsend_run" あたりにしておきます。

#test4-1-3 該当部分のみ抜粋
global "pdfsend_kindle_run";
global "pdfsend_evernote_run";
global "pdfsend_trello_run";

if header :contains "From" "example1.co.jp"
{
  set "pdfsend_check_from" "true";

  set "pdfsend_kindle_run" "true";
  set "kindle_convert" "true";

  set "pdfsend_evernote_run" "true";
  set "evernote_notebook" "テスト1";

  set "pdfsend_trello_run" "true";
  set "trello_assign" "exampleuser1";
}
elsif header :contains "From" "example2.co.jp"
{
  set "pdfsend_check_from" "true";

  set "pdfsend_kindle_run" "true";

  set "pdfsend_evernote_run" "true";
  set "evernote_notebook" "テスト2";

  set "pdfsend_trello_run" "true";
  set "trello_assign" "exampleuser2";
}

if string :count "eq" "${pdfsend_check_from}" "1"
{
  foreverypart
  {
    if header :mime :subtype "Content-Type" "pdf"
    {
      include "pdfsend_run";

      setflag "\\Seen";
# pdfsend_run
require ["include", "variables", "relational"];
global "pdfsend_kindle_run";
global "pdfsend_evernote_run";
global "pdfsend_trello_run";

if string :count "eq" "${pdfsend_kindle_run}" "1"
{
  include "send-kindle";
}
if string :count "eq" "${pdfsend_evernote_run}" "1"
{
  include "send-evernote";
}
if string :count "eq" "${pdfsend_trello_run}" "1"
{
  include "send-trello";
}

ついでに、From: チェック部分も別ファイルに切り出してしまいましょう。

すると、結果として以下のようになります。

#test4-1-4
require ["include", "variables", "fileinto", "imap4flags", "mime", "foreverypart", "relational"];
global "subject";
global "pdfsend_check_from";

# 元メールのSubject:を保存
if header :matches "Subject" "*"
{
  set "subject" "${1}";
}

include "pdfsend_check_from";
if string :count "eq" "${pdfsend_check_from}" "1"
{
  foreverypart
  {
    if header :mime :subtype "Content-Type" "pdf"
    {
      include "pdfsend_run";

      setflag "\\Seen";
      fileinto "Trash";
      break;
    }
  }
}
# pdfsend_check_from
require ["include", "variables"];
global "pdfsend_check_from";
global "pdfsend_kindle_run";
global "pdfsend_evernote_run";
global "pdfsend_trello_run";
global "kindle_convert";
global "evernote_notebook";
global "trello_assign";

if header :contains "From" "example1.co.jp"
{
  set "pdfsend_check_from" "true";

  set "pdfsend_kindle_run" "true";
  set "kindle_convert" "true";

  set "pdfsend_evernote_run" "true";
  set "evernote_notebook" "テスト1";

  set "pdfsend_trello_run" "true";
  set "trello_assign" "exampleuser1";
}
elsif header :contains "From" "example2.co.jp"
{
  set "pdfsend_check_from" "true";

  set "pdfsend_kindle_run" "true";

  set "pdfsend_evernote_run" "true";
  set "evernote_notebook" "テスト2";

  set "pdfsend_trello_run" "true";
  set "trello_assign" "exampleuser2";
}
# pdfsend_run
require ["include", "variables", "relational"];
global "pdfsend_kindle_run";
global "pdfsend_evernote_run";
global "pdfsend_trello_run";

if string :count "eq" "${pdfsend_kindle_run}" "1"
{
  include "send-kindle";
}
if string :count "eq" "${pdfsend_evernote_run}" "1"
{
  include "send-evernote";
}
if string :count "eq" "${pdfsend_trello_run}" "1"
{
  include "send-trello";
}

以上のようになりました。

微妙なバグを修正

動かしてみると分かるのですが、今のコードだとゴミ箱に保管されるメールのSubject:が最後に実行したツールに対するSubject: になってしまっています。普段見ることもないので問題になることは少ないと思いますが、やはり気持ち悪いので修正しておきましょう。

#test4-2-1
require ["include", "variables", "mime", "foreverypart", "relational"];
global "subject";

# 元メールのSubject:を保存
if header :matches "Subject" "*"
{
  set "subject" "${1}";
}

include "pdfsend_check_from";
if string :count "eq" "${pdfsend_check_from}" "1"
{
  foreverypart
  {
    if header :mime :subtype "Content-Type" "pdf"
    {
      include "pdfsend_run";
      break;
    }
  }

  include "trash";
  discard;
}
# trash
require ["include", "copy", "editheader", "variables", "fileinto", "imap4flags"];
global ["subject"];

deleteheader "Subject";
addheader :last "Subject" "${subject}";
setflag "\\Seen";
fileinto :copy "Trash";

PDF以外にも対応してみる

メールを送り込む

今までは、「emailに添付されたPDFドキュメントをどうやって送り込むのか」について解説してきましたが、次に「emailそのものを送り込む方法」についても考えてみることにしましょう。

PDFの場合は "pdfsend" という名前でしたので、ここでは "textsend" あたりにしておくとすると、大雑把に考えると次のようなコードになるでしょうか。

#test4-3-1 (一部のみ抜粋)
include "textsend_checkfrom";
if string :matches "${textsend_check_from}" "true"
{
  include "textsend_run";

  include "trash";
  discard;
}

このコードだけ見ていると十分単純化されているように思えるのですが、よく考えてみると、このコードで呼び出している "textsend_checkfrom" とか、"textsend_run" 等は、PDFの場合とほぼ似たようなコードを繰り返し書かないといけないのが容易に想像がつきます。

もっというと、「PDF」「email」以外に「画像ファイル」やその他多種多様なファイル等、各ツールに送り込みたいものが増えるたびに似たようなコードを毎回書かなきゃいけない必要が出てきて、このままでは非生産的です。ですので、もう少し頭をひねって、「PDF/email/その他送り込みたいもの」を全てひとまとめに「ドキュメント」と定義し直して、コードを整理することにしましょう。

まずは名前を考えます。今回の目的は「ドキュメントを送り込む」と再定義されましたので、"docsend" あたりにしておきましょう。

次に、コード内で呼び出している "textsend_run" と元々存在している "pdfsend_run" を統合します。もちろん名前は、"docsend_run" です。

# docsend_run
require ["include", "variables"];
global "docsend_kindle_run";
global "docsend_evernote_run";
global "docsend_trello_run";

if string :matches "${docsend_kindle_run}" "true"
{
  include "send-kindle";
}
if string :matches "${docsend_evernote_run}" "true"
{
  include "send-evernote";
}
if string :matches "${docsend_trello_run}" "true"
{
  include "send-trello";
}

はい、以前の pdfsend_run と比べて、各変数の名前がpdfからdocに変更になっただけです。

docsend_runで使われている変数は pdfsend_checkfrom で定義されていますので、そちらも変更しましょう。まずは、pdfsend_checkfrom と textsend_checkfrom を統合して、docsend_check_from に名前を変更し、各変数も修正してみます。とりあえず何も考えずに、機械的に修正してみましょう。

# docsend_check_from
require ["include", "variables"];
global "docsend_check_from";
global "docsend_kindle_run";
global "docsend_evernote_run";
global "docsend_trello_run";
global "kindle_convert";
global "evernote_notebook";
global "trello_assign";

if header :contains "From" "example1.co.jp"
{
  set "docsend_check_from" "true";

  set "docsend_kindle_run" "true";
  set "kindle_convert" "true";

  set "docsend_evernote_run" "true";
  set "evernote_notebook" "テスト1";

  set "docsend_trello_run" "true";
  set "trello_assign" "exampleuser1";
}
elsif header :contains "From" "example2.co.jp"
{
  set "docsend_check_from" "true";

  set "docsend_kindle_run" "true";

  set "docsend_evernote_run" "true";
  set "evernote_notebook" "テスト2";

  set "docsend_trello_run" "true";
  set "trello_assign" "exampleuser2";
}

こんな感じでしょうか。繰り返しになりますが、機械的に名前を変更しただけです。

それでは、このdocsend_checkfromを呼び出しているメイン部分を変更してみます。

#test4-3-2 (失敗例)
require ["include", "variables", "mime", "foreverypart"];
global "subject";
global "docsend_check_from";

# 元メールのSubject:を保存
if header :matches "Subject" "*"
{
  set "subject" "${1}";
}

include "docsend_check_from";
if string :matches "${docsend_check_from}" "true"
{
  include "docsend_run";
  include "trash";
}

if string :matches "${docsend_check_from}" "true"
{
  foreverypart
  {
    if header :mime :subtype "Content-Type" "pdf"
    {
      include "docsend_run";
      break;
    }
  }

  include "trash";
}

discard;

おやおや、このコードは意図した動きをしませんね。機械的に統合してしまったために、PDFとemailで同じ動作しかできなくなってしまいました。実際使う場合には、元のコードのように同じ送信元であっても、例えば、evernoteの保存ノートブック名はPDFとemailで変更したりしたいですよね。

原因は「機械的に統合したこと」とはっきり分かっていますので、次回は関係する部分について一つずつ丁寧に見ていくことにしましょう。

まとめ

今回は、コードの不自然な部分やバグを修正したり、ファイルを分割して分かりやすくする、といった作業を行ってみました。

次回は、今回取り組みを始めたPDF以外にも対応する作業を引き続き行います。お楽しみに。

[asin:B07ZWCDYZG:detail] evernote.com trello.com

前回までの記事はこちらです。 tsh.hatenablog.jp tsh.hatenablog.jp tsh.hatenablog.jp tsh.hatenablog.jp tsh.hatenablog.jp