AFEW(1) afew AFEW(1)

afew - اسکریپت برچسب‌گذاری اولیه برای سامانه مدیریت ایمیل notmuch

برنامه afew یک اسکریپت برچسب‌گذاری اولیه برای ایمیل‌های notmuch است:

وظیفه اصلی این برنامه ارائه قابلیت برچسب‌گذاری خودکار در هر بار ثبت ایمیل جدید در notmuch است. در یک ساختار سنتی، می‌توانید آن را پس از دستور notmuch new در هوک پس‌از‌همگام‌سازی (post sync hook) ابزار offlineimap یا در هوک post-new برنامه notmuch فراخوانی کنید.

این ابزار می‌تواند کارهای پایه‌ای مانند افزودن برچسب‌ها بر اساس هدرهای ایمیل یا پوشه‌های maildir، مدیریت رشته‌گفتگوهای بسته‌شده (killed threads) و ایمیل‌های هرزنامه (spam) را انجام دهد.

جهت اطلاع: afew با alot (یک رابط کاربری برای ایمیل notmuch) به خوبی هماهنگ و سازگار است ;)

فهرست مطالب:

مراحل راه‌اندازی و اجرا عبارتند از:

  • نصب بسته afew
  • ایجاد فایل‌های پیکربندی
  • افزودن یک هوک post-new در notmuch که afew را فراخوانی کند

دستورات زیر شما را در سیستم‌های مبتنی بر دبیان/اوبونتو راه‌اندازی می‌کنند:

$ sudo aptitude install notmuch python-notmuch dbacl
$ git clone git://github.com/teythoon/afew.git
$ cd afew
$ python setup.py install --prefix=~/.local

اطمینان حاصل کنید که مسیر ~/.local/bin در متغیر محیطی PATH شما قرار دارد. یک روش برای این کار افزودن قطعه‌کد زیر به فایل ~/.bashrc است:

if [ -d ~/.local/bin ]; then
    PATH=$PATH:~/.local/bin
fi

برای راهنمای دقیق‌تر به بخش «نصب و راه‌اندازی» مراجعه کنید.

اطمینان حاصل کنید که فایل ~/.notmuch-config شامل موارد زیر باشد:

[new]
tags=new

فهرستی از فیلترها را در فایل ~/.config/afew/config قرار دهید:

# This is the default filter chain
[SpamFilter]
[KillThreadsFilter]
[ListMailsFilter]
[ArchiveSentMailsFilter]
[InboxFilter]

و یک هوک post-new برای notmuch ایجاد کنید تا afew را فراخوانی کند:

$ notmuchdir=path/to/maildir/.notmuch
$ mkdir -p "$notmuchdir/hooks"
$ printf > "$notmuchdir/hooks/post-new" '#!/usr/bin/env sh\n$HOME/.local/bin/afew --tag --new\n'
$ chmod u+x "$notmuchdir/hooks/post-new"

شما می‌توانید:

  • برای فیلترسازی سفارشی‌تر فیلترهای اضافی تعریف کنید
  • از حالت جابه‌جایی برای انتقال ایمیل‌های خود بین پوشه‌ها استفاده کنید
  • با اجرای دستور afew --tag --all برنامه afew را روی تمام ایمیل‌های قدیمی خود اجرا کنید
  • توسعه afew و افزودن قابلیت‌های جدید به آن را آغاز کنید

برنامه afew با پایتون +3.6 کار می‌کند و به notmuch و اتصالات پایتون آن نیاز دارد. در سیستم‌های دبیان/اوبونتو می‌توانید آن‌ها را با اجرای دستور زیر نصب کنید:

$ sudo aptitude install notmuch python-notmuch python-dev python-setuptools

نکته: اگر در حال نصب notmuch با استفاده از Homebrew در سیستم‌عامل macOS هستید، حتماً دستور $ brew install --with-python3 notmuch را اجرا کنید، زیرا فرمول brew به طور پیش‌فرض اتصالات python3 notmuch را نصب نمی‌کند.

توصیه می‌شود خود afew را به عنوان یک کاربر بدون دسترسی ریشه درون یک محیط مجازی (virtualenv) نصب کنید؛ چه از طریق دریافت کد منبع و نصب با setup.py و چه از طریق pip.

# create and activate virtualenv
$ python -m venv --system-site-packages .venv
$ source .venv/bin/activate
# install via pip from PyPI:
$ pip install afew
# or install from source:
$ python setup.py install --prefix=~/.local

شاید بخواهید یک پیوند نمادین برای .venv/bin/afew در جایی درون مسیر PATH خود (در این حالت ~/bin/) ایجاد کنید:

$ ln -snr .venv/bin/afew ~/.bin/afew

مستندات را می‌توان در قالب‌های مختلف با استفاده از Sphinx ساخت:

# build docs into build/sphinx/{html,man}
$ python setup.py build_sphinx -b html,man

در نهایت afew یک ابزار خط فرمان است. شما باید یک عملیات (action) و این‌که آیا عملیات روی همه پیام‌ها اعمال شود یا فقط روی پیام‌های جدید را مشخص کنید. عملیات‌هایی که می‌توانید انتخاب کنید عبارتند از:

اجرای فیلترهای برچسب‌گذاری. به بخش «برچسب‌گذاری اولیه» مراجعه کنید.
پایش مداوم صندوق پستی برای فایل‌های جدید
انتقال فایل‌های ایمیل بین پوشه‌های maildir

کارهای پایه برچسب‌گذاری نیازی به پیکربندی ندارند، کافی است اجرا کنید:

$ afew --tag --new
# or to tag *all* messages
$ afew --tag --all

برای انجام خودکار این کار می‌توانید هوک زیر را به فایل ~/.offlineimaprc خود اضافه کنید:

postsynchook = ionice -c 3 chrt --idle 0 /bin/sh -c "notmuch new && afew --tag --new"

نکات بسیار بیشتری درباره پیکربندی فیلترها و فیلترهای مختلف ارائه‌شده توسط afew وجود دارد.

افزودن گزینه --dry-run به هر عملیات --tag یا --sync-tags از اعمال تغییرات در پایگاه داده notmuch جلوگیری می‌کند. افزودن گزینه -vv نیز برای مشاهده جزئیات عملکرد بسیار مفید است.

برای فراخوانی afew در حالت جابه‌جایی، گزینه --move-mails را در خط فرمان مشخص کنید. حالت جابه‌جایی به گزینه --dry-run احترام می‌گذارد، بنابراین می‌توانید گزینه --verbose را اضافه کنید تا تأثیرات یک اجرای واقعی را مشاهده نمایید.

در حالت جابه‌جایی، afew تمام ایمیل‌ها (یا فقط ایمیل‌های اخیر) را در پوشه‌های maildir پیکربندی‌شده بررسی کرده و تصمیم می‌گیرد که آیا باید به پوشه دیگری منتقل شوند یا خیر.

این تصمیم‌گیری بر اساس قوانینی است که در فایل پیکربندی شما تعریف شده‌اند. یک قانون به یک پوشه مبدأ متصل است و یک پوشه مقصد را مشخص می‌کند که در صورت تطابق ایمیل با پرس‌وجوی مربوطه، به آن منتقل خواهد شد.

به این ترتیب می‌توانید اصول مرتب‌سازی خود را تقریباً به ساختار سنتی maildir مبتنی بر پوشه که سرورهای ایمیل کلاسیک متوجه می‌شوند منتقل کنید. ایمیل‌های خود را با notmuch برچسب‌گذاری کنید، دستور afew --move-mails را در یک هوک presynchook ابزار offlineimap فراخوانی کنید و از یک صندوق ورودی مرتب در رابط کاربری وب یا کلاینت گرافیکی خود در محل کار لذت ببرید.

توجه داشته باشید که در حالت جابه‌جایی، afew پس از انتقال ایمیل‌ها دستور notmuch new را فراخوانی می‌کند. می‌توانید از afew -m --notmuch-args=--no-hooks در یک هوک pre-new در notmuch استفاده کنید تا از ایجاد حلقه‌های تکرار بی‌نهایت جلوگیری شود.

برای اطلاعات بیشتر در مورد نحوه پیکربندی قوانین حالت جابه‌جایی و این‌که چه کارهایی می‌توانید با آن انجام دهید و چه کارهایی نمی‌توانید، لطفاً به بخش «حالت جابه‌جایی» مراجعه کنید.

مجموعه کامل گزینه‌ها عبارتند از:

$ afew --help
Usage: afew [options] [--] [query]
Options:
  -h, --help            show this help message and exit
  Actions:
    Please specify exactly one action.
    -t, --tag           run the tag filters
    -w, --watch         continuously monitor the mailbox for new files
    -m, --move-mails    move mail files between maildir folders
  Query modifiers:
    Please specify either --all or --new or a query string.
    -a, --all           operate on all messages
    -n, --new           operate on all new messages
  General options:
    -C NOTMUCH_CONFIG, --notmuch-config=NOTMUCH_CONFIG
                        path to the notmuch configuration file [default:
                        $NOTMUCH_CONFIG or ~/.notmuch-config]
    -e ENABLE_FILTERS, --enable-filters=ENABLE_FILTERS
                        filter classes to use, separated by ',' [default:
                        filters specified in afew's config]
    -d, --dry-run       don't change the db [default: False]
    -R REFERENCE_SET_SIZE, --reference-set-size=REFERENCE_SET_SIZE
                        size of the reference set [default: 1000]
    -T DAYS, --reference-set-timeframe=DAYS
                        do not use mails older than DAYS days [default: 30]
    -v, --verbose       be more verbose, can be given multiple times

شخصی‌سازی فیلترهای برچسب‌گذاری در فایل پیکربندی afew در مسیر ~/.config/afew/config انجام می‌شود.

قالب این فایل شبیه به فایل‌های INI در ویندوز مایکروسافت است. توجه داشته باشید که مقادیر نباید داخل کوتیشن قرار گیرند.

برنامه afew تلاش می‌کند تا خود را با برچسب جدیدی که notmuch روی ایمیل‌های تازه قرار می‌دهد تطبیق دهد، اما بیشتر با برچسب new توسعه یافته و آزمایش شده است. برای استفاده از آن، اطمینان حاصل کنید که فایل ~/.notmuch-config شامل موارد زیر باشد:

[new]
tags=new

برنامه afew مکان پایگاه داده notmuch را از پیکربندی notmuch می‌خواند. هنگامی که هیچ مسیری برای پایگاه داده در پیکربندی notmuch تنظیم نشده باشد، afew مانند ابزار خط فرمان notmuch، در صورت تنظیم بودن متغیر محیطی MAILDIR از آن استفاده می‌کند، یا از $HOME/mail به عنوان پشتیبان بهره می‌گیرد. اگر یک مسیر نسبی ارائه شود، afew همانند notmuch پیشوند $HOME/ را به مسیر اضافه می‌کند (این ویژگی در نسخه 0.28 برنامه notmuch معرفی شد).

شما می‌توانید با استفاده از فایل پیکربندی، فیلترها را اصلاح کنید و نسخه‌های سفارشی خود را از فیلتر پایه تعریف کنید که به شما اجازه می‌دهند پیام‌ها را به روشی مشابه دستور notmuch tag برچسب‌گذاری کنید. فایل پیکربندی پیش‌فرض عبارت است از:

[SpamFilter]
[KillThreadsFilter]
[ListMailsFilter]
[ArchiveSentMailsFilter]
sent_tag = ''
[InboxFilter]

برای مشاهده جزئیات این فیلترها و آرگومان‌های سفارشی که می‌پذیرند، به بخش «فیلترها» مراجعه کنید.

همچنین می‌توانید فیلترهایی بر اساس فیلتر پایه اضافه کنید. این فیلترها را می‌توان با تعیین تنظیمات در زیر آن‌ها شخصی‌سازی کرد. تنظیمات استاندارد که برای تمام فیلترها اعمال می‌شوند عبارتند از:

متنی که در هنگام اجرای این فیلتر در صورت بالا بودن سطح پرگویی (verbosity) نمایش داده می‌شود.
پرس‌وجویی که روی پیام‌ها اعمال می‌شود و در قالب استاندارد notmuch مشخص می‌گردد. توجه داشته باشید که نیازی به مشخص کردن برچسب new ندارید؛ afew هنگام اجرا با فلگ --new آن را به طور خودکار اضافه می‌کند.
برچسب‌هایی که باید برای پیام‌های منطبق با پرس‌وجو اضافه یا حذف شوند. برچسب‌های افزایشی با علامت + و برچسب‌های حذفی با علامت - مشخص می‌شوند. برچسب‌های متعدد با نقطه ویرگول (;) از یکدیگر جدا می‌شوند.
اگر پیامی یکی از این برچسب‌ها را داشته باشد، گزینه tags به آن اضافه نمی‌شود. برچسب‌ها با نقطه ویرگول جدا می‌شوند.

بنابراین برای افزودن برچسب deer به هر پیامی از طرف یا به مقصد antelope@deer.com می‌توانید به صورت زیر عمل کنید:

[Filter.1]
query = 'antelope@deer.com'
tags = +deer
message = Wild animals ahoy

همچنین می‌توانید (در ترکیب با InboxFilter) با حذف برچسب new پیش از رسیدن به InboxFilter، کاری کنید که ایمیل صندوق ورودی (Inbox) را دور بزند:

[Filter.2]
query = from'pointyheaded@boss.com'
tags = -new;+boss
message = Message from above

نمایش چند نمونه پیکربندی ساده‌ترین روش برای درک موضوع است. صفحه برچسب‌گذاری اولیه notmuch در نشانی http://notmuchmail.org/initial_tagging یک نمونه پیکربندی را نشان می‌دهد:

# immediately archive all messages from "me"
notmuch tag -new -- tag:new and from:me@example.com
# delete all messages from a spammer:
notmuch tag +deleted -- tag:new and from:spam@spam.com
# tag all message from notmuch mailing list
notmuch tag +notmuch -- tag:new and to:notmuch@notmuchmail.org
# finally, retag all "new" messages "inbox" and "unread"
notmuch tag +inbox +unread -new -- tag:new

پیکربندی معادل (تقریبی) در afew به شرح زیر خواهد بود:

[ArchiveSentMailsFilter]
[Filter.1]
message = Delete all messages from spammer
query = from:spam@spam.com
tags = +deleted;-new
[Filter.2]
message = Tag all messages from the notmuch mailing list
query = to:notmuch@notmuchmail.org
tags = +notmuch
[InboxFilter]

توجه داشته باشید که پرس‌وجوها عموماً شامل tag:new نمی‌شوند زیرا این مورد هنگام اجرای afew با فلگ --new به صورت ضمنی لحاظ می‌شود.

تفاوت‌های میان آن‌ها به شرح زیر است:

  • فیلتر ArchiveSentMailsFilter علاوه بر بایگانی کردن ایمیل، برچسب‌های مشخص‌شده در گزینه sent_tag را نیز اضافه می‌کند (مقدار پیش‌فرض '' به معنی عدم افزودن برچسب است؛ شاید بخواهید آن را روی sent تنظیم کنید). همچنین ایمیل‌هایی را که به یکی از آدرس‌های خودتان ارسال شده باشد بایگانی نمی‌کند.
  • فیلتر InboxFilter برچسب unread را اضافه نمی‌کند. با این حال بیشتر کلاینت‌های ایمیل وضعیت خوانده‌نشده را مستقیماً در maildir مدیریت می‌کنند.

در این‌جا چند نمونه فیلتر دیگر از دات‌فایل‌های گیت‌هاب آورده شده است:

[Filter.1]
query = sicsa-students@sicsa.ac.uk
tags = +sicsa
message = sicsa
[Filter.2]
query = from:foosoc.ed@gmail.com OR from:GT Silber OR from:lizzie.brough@eusa.ed.ac.uk
tags = +soc;+foo
message = foosoc
[Filter.3]
query = folder:gmail/G+
tags = +G+
message = gmail spam
# skip inbox
[Filter.6]
query = to:notmuch@notmuchmail.org AND (subject:emacs OR subject:elisp OR "(defun" OR "(setq" OR PATCH)
tags = -new
message = notmuch emacs stuff
# Assuming the following workflow: all messages for projects or releases should be tagged
# as "project/A", "project/B" respectively "release/1.0.1" or "release/1.2.0".
#
# In most cases replies to messages retain their context: the project, the release(s), ..
#
# The following config will propagate all project/... or release/... tags from a thread
# to all new messages.
[PropagateTagsByRegexInThreadFilter.1]
propagate_tags = project/.*
# do not tag spam
filter = not is:spam
[PropagateTagsByRegexInThreadFilter.2]
propagate_tags = release/.*

مجموعه فیلترهای پیش‌فرض (در صورتی که چیزی در فایل پیکربندی مشخص نکنید) عبارت است از:

[SpamFilter]
[KillThreadsFilter]
[ListMailsFilter]
[ArchiveSentMailsFilter]
[InboxFilter]

پیکربندی استاندارد فیلترها را می‌توان برای این فیلترها نیز اعمال کرد. با این حال توجه داشته باشید که اکثر فیلترهای زیر مقدار اختصاصی خود را برای message، query و/یا tags تنظیم می‌کنند و برخی از آن‌ها بعضی تنظیمات استاندارد را نادیده می‌گیرند.

این فیلتر SentMailsFilter را با ویژگی‌های زیر گسترش می‌دهد:

•
برچسب new از ایمیل‌های فیلترشده توسط این فیلتر حذف می‌شود، بنابراین برچسب inbox توسط InboxFilter به آن‌ها اضافه نخواهد شد.

این فیلتر امضاهای DKIM مربوط به ایمیل‌های دارای هدر DKIM را اعتبارسنجی کرده و برچسب‌های dkim-ok یا dkim-fail را اضافه می‌کند.

گزارش‌های DMARC معمولاً در قالب فایل‌های ZIP ارسال می‌شوند. برای بررسی گزارش باید فایل را استخراج کرده و درون سند XML جستجو کنید که کاری بسیار خسته‌کننده و وقت‌گیر است. این فیلتر پیام را به صورت زیر برچسب‌گذاری می‌کند:

اگر در هر یک از پیوست‌ها خطای SPF وجود داشته باشد، پیام با برچسب "dmarc-spf-fail" برچسب‌گذاری می‌شود، در غیر این صورت با برچسب "dmarc-spf-ok" برچسب‌گذاری خواهد شد.

اگر در هر یک از پیوست‌ها خطای DKIM وجود داشته باشد، پیام با برچسب "dmarc-dkim-fail" برچسب‌گذاری می‌شود، در غیر این صورت با برچسب "dmarc-dkim-ok" برچسب‌گذاری خواهد شد.

برای هر ایمیل، تمام پوشه‌هایی را که ایمیل در آن‌ها قرار دارد بررسی می‌کند و از مسیر و نام فایل به عنوان برچسبی برای آن ایمیل استفاده می‌کند. بنابراین اگر ساختاری با procmail یا sieve دارید که ایمیل‌ها را در پوشه‌ها قرار می‌دهد، این فیلتر می‌تواند بسیار مفید باشد.

•
folder_explicit_list = <folder list>
  • ایمیل‌ها را فقط با برچسب‌های موجود در <folder list> برچسب‌گذاری می‌کند. <folder list> فهرستی است که با فاصله جدا شده و داخل کوتیشن یا نماد دیگری قرار نمی‌گیرد.
  • فهرست خالی به معنای همه پوشه‌ها است (البته لیست سیاه همچنان اعمال می‌شود).
  • مقدار پیش‌فرض یک فهرست خالی است.
  • می‌توانید از آن برای مثال جهت تنظیم برچسب‌ها فقط برای پوشه‌های خاص مانند 'Sent' استفاده کنید.
•
folder_blacklist = <folder list>
  • هرگز ایمیل‌ها را با برچسب‌های موجود در <folder list> برچسب‌گذاری نمی‌کند. <folder list> فهرستی است که با فاصله جدا شده و داخل کوتیشن یا نماد دیگری قرار نمی‌گیرد.
  • مقدار پیش‌فرض این است که هیچ پوشه‌ای در لیست سیاه نباشد.
  • می‌توانید از آن برای مثال جهت جلوگیری از برچسب‌گذاری ایمیل‌ها به عنوان 'INBOX' هنگامی که برچسب استانداردتر 'inbox' وجود دارد استفاده کنید.
•
folder_transforms = <transformation rules>
  • نام پوشه‌ها را بر اساس قوانین مشخص‌شده قبل از برچسب‌گذاری ایمیل‌ها تبدیل می‌کند. <transformation rules> یک فهرست جداشده با فاصله شامل جفت‌های به سبک 'folder:tag' است. دونقطه (:) نام پوشه‌ای را که باید تبدیل شود از برچسبی که باید به آن تبدیل شود جدا می‌کند.
  • رفتار پیش‌فرض تبدیل به نام پوشه‌ها است.
  • می‌توانید از قوانین مثلاً برای تبدیل نام پوشه 'Junk' به برچسب 'spam' یا اصلاح بزرگی/کوچکی حروف پوشه‌های پیش‌نویس (draft) و ارسالی (sent) استفاده کنید:
folder_transforms = Junk:spam Drafts:draft Sent:sent
•
folder_lowercases = true
•
استفاده از برچسب‌های حروف کوچک برای تمام نام‌های پوشه‌ها
•
maildir_separator = <sep>
  • استفاده از <sep> برای تقسیم سلسله‌مراتب maildir به برچسب‌های مجزا.
  • پیش‌فرض جداسازی با '.' است.
  • اگر سلسله‌مراتب maildir شما در سیستم فایل به صورت دایرکتوری‌های جمع‌شده (collapsed dirs) نمایش داده می‌شود، از <sep> برای تقسیم مجدد آن پیش از اعمال برچسب‌ها استفاده می‌شود. اگر ساختار maildir شما به این شکل باشد:
[...]
/path/to/maildir/devel.afew/[cur|new|tmp]/...
/path/to/maildir/devel.alot/[cur|new|tmp]/...
/path/to/maildir/devel.notmuch/[cur|new|tmp]/...
[...]

ایمیل‌های موجود در پوشه afew شما با برچسب‌های 'devel' و 'afew' برچسب‌گذاری خواهند شد.

اگر در مقابل، سلسله‌مراتب شما با یک جداکننده متعارف‌تر مانند '/' یا هر جداکننده دیگری تقسیم شده باشد:

[...]
/path/to/maildir/devel/afew/[cur|new|tmp]/...
/path/to/maildir/devel/alot/[cur|new|tmp]/...
/path/to/maildir/devel/notmuch/[cur|new|tmp]/...
[...]

لازم است آن جداکننده را پیکربندی کنید تا ایمیل‌های شما به درستی برچسب‌گذاری شوند:

maildir_separator = /

این فیلتر در صورتی که هدر مشخص‌شده با عبارت باقاعده داده‌شده مطابقت داشته باشد، برچسب‌هایی را به پیام اضافه می‌کند. برچسب‌ها می‌توانند مقادیر ثابتی باشند یا بر اساس تطابق تعیین شوند. تنظیماتی که می‌توانید استفاده کنید عبارتند از:

  • header = <header_name>
  • pattern = <regex_pattern>
  • tags = <tag_list>

اگر برچسبی را در داخل {} قرار دهید، با بخش تطابق‌یافته نام‌گذاری‌شده جایگزین خواهد شد.

چند مثال عبارتند از:

[HeaderMatchingFilter.1]
header = X-Spam-Flag
pattern = YES
tags = +spam
[HeaderMatchingFilter.2]
header = List-Id
pattern = <(?P<list_id>.*)>
tags = +lists;+{list_id}
[HeaderMatchingFilter.3]
header = X-Redmine-Project
pattern = (?P<project>.+)
tags = +redmine;+{project}

فیلترهای SpamFilter و ListMailsFilter با استفاده از HeaderMatchingFilter پیاده‌سازی شده‌اند و تنها کمی پیچیده‌تر از مثال‌های فوق هستند.

این فیلتر برچسب new را حذف کرده و برچسب inbox را به هر پیامی که بسته نشده باشد (killed) یا هرزنامه (spam) نباشد اضافه می‌کند. (برچسب‌های جدید در پیکربندی notmuch شما تنظیم می‌شوند و پیش‌فرض آن‌ها فقط new است).

اگر پیام جدید به رشته‌گفتگویی اضافه شده باشد که قبلاً با killed برچسب‌گذاری شده است، برچسب killed را به این پیام اضافه می‌کند. این ویژگی امکان نادیده گرفتن تمام پاسخ‌های یک رشته‌گفتگوی خاص را فراهم می‌سازد.

این فیلتر به دنبال هدر List-Id می‌گردد و در صورت یافتن آن، برچسب lists و برچسبی با نام lists/<list-id> را اضافه می‌کند.

فیلتری اضافه می‌کند که ایمیل‌های ارسال‌شده مستقیم به هر یک از آدرس‌های تعریف‌شده در فایل پیکربندی Notmuch (primary_email یا other_email) را برچسب‌گذاری می‌کند. برچسب پیش‌فرض to-me است و می‌تواند با گزینه me_tag سفارشی‌سازی شود.

تنظیماتی که می‌توانید استفاده کنید عبارتند از:

•
sent_tag = <tag>
  • افزودن <tag> به تمام ایمیل‌هایی که از یکی از آدرس‌های ایمیل پیکربندی‌شده شما ارسال شده‌اند، و نه به هیچ‌یک از آدرس‌های شما.
  • پیش‌فرض این است که هیچ برچسبی اضافه نشود، بنابراین باید مقداری را مشخص کنید.
  • می‌توانید مثلاً از آن برای برچسب‌گذاری تمام ایمیل‌های ارسالی توسط خودتان با عنوان 'sent' استفاده کنید. این کار به ویژه در ارتباط با یک کلاینت ایمیل که قادر است علاوه بر رشته‌گفتگوها، ایمیل‌های مجزا را نیز جستجو کند، منطقی و سودمند خواهد بود.
•
to_transforms = <transformation rules>
  • تبدیل آدرس‌های ایمیل To/Cc/Bcc به برچسب‌ها طبق قوانین مشخص‌شده. <transformation rules> یک فهرست جداشده با فاصله است که از جفت‌های به سبک <'user_part@domain_part>:tags' تشکیل شده است. دونقطه (:) آدرس ایمیلی را که باید تبدیل شود از برچسب‌هایی که باید به آن تبدیل شود جدا می‌کند. بخش ':tags' اختیاری است و در صورت خالی بودن، از 'user_part' به عنوان برچسب استفاده می‌شود. مقدار 'tags' می‌تواند یک برچسب واحد یا فهرستی از برچسب‌های جداشده با نقطه ویرگول باشد.
  • می‌توان از آن برای مثال برای برچسب‌گذاری آسان پیام‌های ارسال‌شده به لیست‌های پستی که در این مرحله فاقد فیلد List-Id هستند استفاده کرد.

تنظیماتی که می‌توانید استفاده کنید عبارتند از:

•
spam_tag = <tag>
  • افزودن <tag> به تمام ایمیل‌هایی که به عنوان هرزنامه شناسایی شده‌اند.
  • پیش‌فرض 'spam' است.
  • می‌توانید از آن برای برچسب‌گذاری هرزنامه‌های خود با عناوینی مانند 'junk'، 'scum' یا هر چیز دیگری که ترجیح می‌دهید استفاده کنید. توجه داشته باشید که در این‌جا تنها یک برچسب واحد پشتیبانی می‌شود.

در صورتی که هدر X-Spam-Flag وجود داشته باشد، ایمیل به عنوان هرزنامه در نظر گرفته می‌شود.

برای شخصی‌سازی این فیلترها، اساساً دو روش مختلف وجود دارد:

فرض کنید فیلتر SpamFilter را دوست دارید، اما رفتار آن بیش از حد مؤدبانه است:

1.
ایجاد یک شیء فیلتر و شخصی‌سازی آن
[SpamFilter.0] # note the index
message = meh

اگر بخواهید یک SpamFilter جدید علاوه بر فیلتر پیش‌فرض بسازید، درج ایندکس الزامی است. اگر فقط به یک SpamFilter سفارشی‌شده نیاز دارید، می‌توانید ایندکس را حذف کرده و نمونه پیش‌فرض را شخصی‌سازی کنید.

2.
ایجاد یک نوع جدید...
[ShitFilter(SpamFilter)]
message = I hatez teh spam!

و ایجاد یک یا دو شیء

[ShitFilter.0]
[ShitFilter.1]
message = Me hatez it too.

همچنین می‌توانید پیاده‌سازی‌های فیلتر اختصاصی خود را ارائه دهید. شما باید فیلترهای خود را از طریق نقاط ورود (entry points) ثبت کنید. برای مشاهده مثال‌هایی درباره نحوه ثبت فیلترها به فایل setup.py برنامه afew مراجعه کنید. برای افزودن فیلترهای خود، کافی است بسته خود را در بستر برنامه afew نصب کنید.

در این‌جا یک نمونه پیکربندی کامل برای حالت جابه‌جایی آورده شده است:

[MailMover]
folders = INBOX Junk
rename = False
max_age = 15
# rules
INBOX = 'tag:spam':Junk 'NOT tag:inbox':Archive
Junk = 'NOT tag:spam AND tag:inbox':INBOX 'NOT tag:spam':Archive

در ادامه معنای هر بخش از این پیکربندی را توضیح می‌دهیم.

ابتدا باید مشخص کنید کدام پوشه‌ها باید برای ایمیل‌هایی که قرار است منتقل شوند بررسی گردند (به صورت فهرستی جداشده با فضای خالی). نام پوشه‌هایی که شامل فضای خالی هستند باید در داخل کوتیشن قرار گیرند:

folders = INBOX Junk "Sent Mail"

سپس باید قوانینی را مشخص کنید که عملیات جابه‌جایی را به فرم زیر تعریف می‌کنند:

<src> = ['<qry>':<dst>]+

هر ایمیلی در پوشه <src> که با یک <qry> مطابقت داشته باشد، به پوشه <dst> مرتبط با آن پرس‌وجو منتقل خواهد شد. پیامی که با چندین پرس‌وجو مطابقت داشته باشد، در چندین مقصد کپی خواهد شد.

می‌توانید هر تعداد قانونی را که لازم می‌دانید به یک پوشه maildir متصل کنید. کافی است آن‌ها را به عنوان عناصر یک فهرست (جداشده با فضای خالی) اضافه کنید.

با این حال لطفاً توجه داشته باشید که برای استفاده از حالت جابه‌جایی، باید حداقل یک قانون برای هر پوشه تعیین‌شده در گزینه folders و حداقل یک پوشه برای بررسی مشخص کنید.

INBOX = 'tag:spam':Junk

دستور فوق یک قانون را به پوشه maildir با نام INBOX متصل می‌کند که بیان می‌دارد تمام ایمیل‌های موجود در پوشه مذکور که (احتمالاً در میان سایر برچسب‌ها) دارای برچسب spam هستند باید به پوشه Junk منتقل شوند.

با توجه به این‌که <qry> یک پرس‌وجوی اختیاری notmuch است، شما این امکان را دارید که قوانینی با انعطاف‌پذیری دلخواه بسازید. می‌توانید عدم وجود برچسب‌ها را بررسی کنید و به دنبال ترکیب ویژگی‌ها باشید:

Junk = 'NOT tag:spam AND tag:inbox':INBOX 'NOT tag:spam':Archive

قوانین فوق تمام ایمیل‌های موجود در Junk را که فاقد برچسب spam اما دارای برچسب inbox هستند به پوشه INBOX منتقل می‌کنند. سایر ایمیل‌هایی که با spam برچسب‌گذاری نشده‌اند به Archive منتقل خواهند شد.

می‌توانید قدمت ایمیل‌هایی را که می‌خواهید منتقل شوند با تنظیم گزینه max_age در بخش پیکربندی محدود کنید. با قرار دادن مقدار

max_age = 15

برنامه afew فقط ایمیل‌هایی را با حداکثر ۱۵ روز قدمت بررسی خواهد کرد.

اگر از ابزار همگام‌سازی IMAP با نام mbsync استفاده می‌کنید، این گزینه را فعال کنید. ابزار mbsync هنگام همگام‌سازی فایل‌ها، یک شناسه یکتا به نام آن‌ها اضافه می‌کند. اگر گزینه rename تنظیم نشده باشد، جابه‌جایی فایل‌ها می‌تواند باعث تداخل شناسه UID شده و از همگام‌سازی mbsync با پیام‌های خطایی مانند "Maildir error: duplicate UID 1234" یا "UID 567 is beyond highest assigned UID 89" جلوگیری کند.

هنگامی که این گزینه فعال باشد، afew فایل‌ها را هنگام جابه‌جایی تغییر نام داده و UID را حذف می‌کند اما سایر اطلاعات mbsync را حفظ می‌نماید. این کار به mbsync اجازه می‌دهد تا یک UID جدید به فایل اختصاص دهد و از تداخل‌های UID جلوگیری شود.

اگر از offlineimap استفاده می‌کنید، می‌توانید با خیال راحت این گزینه را نادیده بگیرید.

rename = True

(1) قوانین برچسب‌ها را تغییر نمی‌دهند.

INBOX = 'NOT tag:inbox':Archive
Junk = 'NOT tag:spam':INBOX

ترکیب قوانین بالا ممکن است پیچیده و گمراه‌کننده باشد، زیرا ممکن است انتظار داشته باشید ایمیل‌های پاک‌سازی‌شده از اسپم سر از INBOX درآورند. اما از آن‌جا که قانون Junk برچسب inbox را اضافه نمی‌کند، اجرای بعدی در حالت جابه‌جایی ممکن است ایمیل‌های منطبق را به Archive منتقل کند.

از طرفی، اگر برچسب spam را حذف کنید و برچسب inbox را تنظیم نکنید، چگونه انتظار دارید ایمیل پس از جابه‌جایی در پوشه INBOX شما قرار گیرد؟ ;)

(2) هیچ نگاشت یک‌به‌یک (1:1) بین پوشه‌ها و برچسب‌ها وجود ندارد؛ و این یک قابلیت است. اگر پیامی را با دو برچسب نشانه‌گذاری کنید و برای هر یک از آن‌ها قانونی وجود داشته باشد، هر دو قانون اعمال خواهند شد. ایمیل شما در دو پوشه مقصد کپی شده و سپس از مکان اصلی خود حذف خواهد شد.

می‌توانید فایل‌های پایتون را در مسیر ~/.config/afew/ قرار دهید تا توسط afew فراخوانی و وارد (import) شوند. اگر از آن فایل پایتون برای تعریف یک کلاس Filter استفاده کرده و از دکوراتور register_filter بهره بگیرید، می‌توانید در پیکربندی فیلترهای خود به آن ارجاع دهید.

یک نمونه از یک فیلتر کوچک که می‌توانید اضافه کنید عبارت است از:

from afew.filters.BaseFilter  import Filter
from afew.FilterRegistry import register_filter
PROJECT_MAPPING = {
    'fabric': 'deployment',
    'oldname': 'new-name',
}
@register_filter
class RedmineFilter(Filter):
    message = 'Create tag based on redmine project'
    query = 'NOT tag:redmine'
    def handle_message(self, message):
        project = message.get_header('X-Redmine-Project')
        if project in PROJECT_MAPPING:
            project = PROJECT_MAPPING[project]
        self.add_tags(message, 'redmine', project)

ما متغیرهای کلاسی message و query را تعریف کرده‌ایم که توسط کلاس والد Filter استفاده می‌شوند. مقدار message هنگام اجرا با فلگ‌های پرگویی چاپ می‌شود. مقدار query برای انتخاب پیام‌ها جهت اجرا استفاده می‌شود؛ در این‌جا ما اطمینان حاصل می‌کنیم که پیام‌هایی را که قبلاً بررسی کرده‌ایم مجدداً پردازش نکنیم.

متد handle_message() متد اصلی برای پیاده‌سازی است. این متد برای هر پیامی که با پرس‌وجو مطابقت داشته باشد فراخوانی می‌شود. آرگومان ورودی یک شیء پیام notmuch است: http://pythonhosted.org/notmuch/#message-a-single-message و متدهای کلیدی استفاده‌شده توسط فیلترهای afew عبارتند از: header()، filename() و get_thread().

از میان متدهای به ارث برده‌شده از کلاس Filter، متدهای اصلی عبارتند از add_tags() و remove_tags()، اما برای ایده‌های بیشتر بخش «پیاده‌سازی» را مطالعه کنید یا مستقیماً به کد منبع مراجعه فرمایید.

هنگامی که فیلتر خود را تعریف کردید، می‌توانید آن را مانند هر فیلتر دیگری به پیکربندی خود اضافه کنید:

[RedmineFilter]

طراحی بخش مدیریت پایگاه داده از مدیر پایگاه داده alot با نام alot.db.DBManager الهام گرفته شده است.

پوشش راحت و تسهیل‌کننده برای notmuch.
پیام داده‌شده را به نمایه (index) برنامه notmuch اضافه می‌کند.
پارامترها (Parameters)
خطاهای پرتابی (Raises)
خطای notmuch.NotmuchError در صورتی که افزودن پیام با شکست مواجه شود
مقادیر بازگشتی (Returns)
یک شیء notmuch.Message
در صورت باز بودن پایگاه داده notmuch، آن را می‌بندد.
یک پرس‌وجوی notmuch را اجرا می‌کند.
پارامترها (Parameters)
query (str https://docs.python.org/3/library/stdtypes.html#str) -- پرس‌وجو برای اجرا
مقادیر بازگشتی (Returns)
نتیجه پرس‌وجو
نوع بازگشتی (Return type)
notmuch.Query
دریافت تمام پیام‌های منطبق با پرس‌وجوی داده‌شده.
پارامترها (Parameters)
مقادیر بازگشتی (Returns)
یک تکرارکننده (iterator) بر روی اشیاء notmuch.Message
پیام داده‌شده را از نمایه notmuch حذف می‌کند.
پارامترها (Parameters)
path (str https://docs.python.org/3/library/stdtypes.html#str) -- مسیر پیام
تمام پاسخ‌های داده‌شده به پیام مشخص را برمی‌گرداند.
پارامترها (Parameters)
message (notmuch.Message) -- پیامی که باید از آن شروع شود
مقادیر بازگشتی (Returns)
یک تکرارکننده (iterator) بر روی اشیاء notmuch.Message
تمام پیام‌های موجود در رشته‌گفتگوی داده‌شده را برمی‌گرداند.
پارامترها (Parameters)
thread (notmuch.Thread) -- رشته‌گفتگوی مورد نظر
مقادیر بازگشتی (Returns)
یک تکرارکننده (iterator) بر روی اشیاء notmuch.Message

ساختارهای داده‌ای را که تغییرات در صف پایگاه داده notmuch را نگه می‌دارند، (مجدداً) مقداردهی اولیه می‌کند.

  • نمایه (Index)
  • نمایه ماژول‌ها (Module Index)
  • صفحه جستجو (Search Page)

Justus Winter

afewmail project

July 22, 2026 4.0.2