-
Notifications
You must be signed in to change notification settings - Fork 0
teleshoes/qtemail
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Copyright 2015 by Elliot Wolk This project is free software, released under the GPLv3 smtp-cli Copyright Michal Ludvig 2003-2014 smtp-cli is free software, released under the GPLv3 small changes to smtp-cli Copyright 2015 Elliot Wolk qmlcompletionbox Copyright 2013 Vyacheslav Blinov qmlcompletionbox is free software, released under the GPLv2 qmlcompletionbox is based on SuggestionBox.qml from liquid browser liquid Copyright 2011 Jocelyn Turcotte liquid is free software, released under the GPLv2 Simple IMAP client with a QT gui and a CLI Minimal dependencies, currently minimal features icons: Blue Magic by RevZAP https://www.iconfinder.com/iconsets/blue-magic WooCons #1 by Janik Baumgartner http://www.woothemes.com/2010/08/woocons1 Knob Buttons Toolbar icons by iTweek http://itweek.deviantart.com/art/Knob-Buttons-Toolbar-icons-73463960 Diagram by Double-J designs https://www.iconfinder.com/iconsets/diagram FILES src/email-gui.py simple python QT gui (pyside+QML) essentially a wrapper around email.pl should work anywhere QT/python/perl work with little effort explicitly supported platforms: Sailfish OS Debian GNU/Linux QML is located in /opt/email-gui/ src/email.pl simple command line IMAP client caches all headers, and caches unread bodies e.g.: > echo "configure $HOME/.secrets first" configure /home/wolke/.secrets and run 'email.pl' > > email.pl GMail: logging in fetching all message ids fetched 15906 ids caching headers for 15906 messages caching bodies for 1 messages > > email.pl --summary GMail 2015-01-20 11:10:01 "Naked Girls Reading NYC" <ngrnyc@gmail.com> Join us tomorrow night for SCIENCE! > > email.pl --print ACCOUNT: GMail UID: 35870 DATE: Tue, 20 Jan 2015 11:10:01 -0500 FROM: "Naked Girls Reading NYC" <ngrnyc@gmail.com> SUBJECT: Join us tomorrow night for SCIENCE! BODY: This November, the Naked Girls give it all away as Naked Girls Reading presents SPOILER ALERT! Join the hit nude literary salon for an evening... > > email.pl --unread-line && echo G1 > email.pl --body G 35870 | grep -o '<div>' | wc -l 0 > email.pl --body-html G 35870 | grep -o '<div>' | wc -l 12 src/email-search.pl builds and queries a sqlite database for header information like subject/to/from e.g.: > email-search.pl --updatedb G inbox all updatedb: all:19128 cached:19128 uncached:0 adding:0 no UIDs to add > email-search.pl --search G 'bananas' 23654 23741 23777 src/smtp-cli SMTP command line client, written by Michal Ludvig https://github.com/mludvig/smtp-cli src/bash-complete.pl helper script that generates bash completion words bashcompletion/qtemail bash completion script that invokes bash-complete.pl ~/.secrets Account config goes here. See "Usage" below. Dependencies: perl perl modules: Mail::IMAPClient IO::Socket::SSL MIME::Parser Date::Parse Date::Format MIME::Lite python pyside qt qtquick 1.1 sqlite Usage: ===== email.pl ===== Simple IMAP client. {--smtp command is a convenience wrapper around smtp-cli} Configuration is in ~/.secrets Each config entry is one line of the format: email.GLOBAL_OPTION_KEY = <value> or email.ACCOUNT_NAME.ACCOUNT_CONFIG_KEY = <value> Account names can be any word characters (alphanumeric plus underscore) Lines that do not begin with "email." are ignored. ACCOUNT_NAME: the word following "email." in ~/.secrets FOLDER_NAME: "inbox", "sent" or one of the names from "folders" UID: an IMAP UID {UIDVALIDITY is assumed to never change} GLOBAL_OPTION_KEY: update_cmd [OPT] command to run after all updates encrypt_cmd [OPT] command to encrypt passwords on disk decrypt_cmd [OPT] command to decrypt saved passwords ACCOUNT_CONFIG_KEY: user [REQ] IMAP username, usually the full email address password [REQ] password, stored with optional encrypt_cmd server [REQ] IMAP server, e.g.: "imap.gmail.com" port [REQ] IMAP server port smtp_server [OPT] SMTP server, e.g.: "smtp.gmail.com" smtp_port [OPT] SMTP server port ssl [OPT] set to false to forcibly disable security inbox [OPT] primary IMAP folder name (default="INBOX") sent [OPT] IMAP folder name to use for sent mail, e.g.:"Sent" folders [OPT] extra IMAP folders to fetch (sep=":") the FOLDER_NAME used as the dir on the filesystem has non-alphanumeric substrings replaced with _s and all leading and trailing _s removed e.g.: email.Z.folders = junk:[GMail]/Drafts:_12_/ponies => ["junk", "gmail_drafts", "12_ponies"] count_include [OPT] FOLDER_NAMEs for counts (default="inbox", sep=":") list of FOLDER_NAMEs for account-wide unread/total counts this controls what gets written to the global unread file, and what is returned by --accounts note this is the FOLDER_NAME, and not the IMAP folder e.g.: email.Z.sent = [GMail]/Sent Mail email.Z.folders = [GMail]/Spam:[GMail]/Drafts email.Z.count_include = inbox:gmail_spam:sent => included: INBOX, [GMail]/Spam, [GMail]/Sent Mail excluded: [GMail]/Drafts skip [OPT] set to true to skip during --update body_cache_mode [OPT] one of [unread|all|none] (default="unread") controls which bodies get cached during --update (note: only caches the first MAX_BODIES_TO_CACHE=100) unread: cache unread bodies (up to 100) all: cache all bodies (up to 100) none: do not cache bodies during --update prefer_html [OPT] prefer html over plaintext (default="false") new_unread_cmd [OPT] custom alert command update_interval [OPT] GUI: seconds between account updates refresh_interval [OPT] GUI: seconds between account refresh filters [OPT] GUI: list of filter-buttons, e.g.:"s1=%a% s2=%b%" each filter is separated by a space, and takes the form: <FILTER_NAME>=%<FILTER_STRING>% FILTER_NAME: the text of the button in the GUI FILTER_STRING: query for /opt/qtemail/bin/email-search.pl e.g.: email.Z.filters = mary=%from~"mary sue"% ok=%body!~viagra% => ["mary", "ok"] /opt/qtemail/bin/email.pl -h|--help show this message /opt/qtemail/bin/email.pl [--update] [--folder=FOLDER_NAME_FILTER] [ACCOUNT_NAME ACCOUNT_NAME ...] -for each account specified {or all non-skipped accounts if none are specified}: -login to IMAP server, or create file ~/.cache/email/ACCOUNT_NAME/error -for each FOLDER_NAME {or just FOLDER_NAME_FILTER if specified}: -fetch and write all message UIDs to ~/.cache/email/ACCOUNT_NAME/FOLDER_NAME/all -fetch and cache all message headers in ~/.cache/email/ACCOUNT_NAME/FOLDER_NAME/headers/UID -fetch and cache bodies according to body_cache_mode config all => every header that was cached gets its body cached unread => every unread message gets its body cached none => no bodies are cached ~/.cache/email/ACCOUNT_NAME/FOLDER_NAME/bodies/UID -fetch all unread messages and write their UIDs to ~/.cache/email/ACCOUNT_NAME/FOLDER_NAME/unread -write all message UIDs that are now in unread and were not before ~/.cache/email/ACCOUNT_NAME/FOLDER_NAME/new-unread -run /opt/qtemail/bin/email-search.pl --updatedb ACCOUNT_NAME FOLDER_NAME 100 -update global unread counts file ~/.cache/email/unread-counts count the unread emails for each account in the folders in count_include the default is just to include the counts for "inbox" write the unread counts, one line per account, to ~/.cache/email/unread-counts e.g.: 3:AOL 6:GMAIL 0:WORK_GMAIL /opt/qtemail/bin/email.pl --smtp ACCOUNT_NAME SUBJECT BODY TO [ARG ARG ..] simple wrapper around smtp-cli. {you can add extra recipients with --to} calls: /opt/qtemail/bin/smtp-cli \ --server=<smtp_server> --port=<smtp_port> \ --user=<user> --pass=<password> \ --from=<user> \ --subject=SUBJECT --body-plain=BODY \ --to=TO \ ARG ARG .. /opt/qtemail/bin/email.pl --mark-read [--folder=FOLDER_NAME] ACCOUNT_NAME UID [UID UID ...] login and mark the indicated message(s) as read /opt/qtemail/bin/email.pl --mark-unread [--folder=FOLDER_NAME] ACCOUNT_NAME UID [UID UID ...] login mark the indicated message(s) as unread /opt/qtemail/bin/email.pl --delete [--folder=FOLDER_NAME] ACCOUNT_NAME UID [UID UID ...] delete the indicated messages (from IMAP server AND local cache) /opt/qtemail/bin/email.pl --delete-local [--folder=FOLDER_NAME] ACCOUNT_NAME UID [UID UID ...] delete the indicated messages from the local cache ONLY (does not delete from IMAP server) /opt/qtemail/bin/email.pl --move [--folder=FOLDER_NAME] ACCOUNT_NAME DEST_FOLDER_NAME UID [UID UID ...] move the indicated messages on the IMAP server from FOLDER_NAME to DEST_FOLDER_NAME this deletes the indicated messages from the local cache. this does NOT, however, download the newly moved messages in DEST_FOLDER_NAME; you need to update DEST_FOLDER_NAME to fetch them from the IMAP server /opt/qtemail/bin/email.pl --accounts format and print information about each account "ACCOUNT_NAME:<timestamp>:<relative_time>:<update_interval>s:<unread_count>/<total_count>:<error>" /opt/qtemail/bin/email.pl --folders ACCOUNT_NAME format and print information about each folder for the given account "FOLDER_NAME:<unread_count>/<total_count>" /opt/qtemail/bin/email.pl --header [--folder=FOLDER_NAME] ACCOUNT_NAME UID [UID UID ...] format and print the header of the indicated message(s) prints each of [Date Subject From To CC BCC] one per line, formatted "UID.FIELD: VALUE" /opt/qtemail/bin/email.pl --body [--no-download] [-0] [--folder=FOLDER_NAME] ACCOUNT_NAME UID [UID UID ...] download, format and print the body of the indicated message(s) if -0 is specified, print a NUL character after each body instead of a newline if body is cached, skip download if body is not cached and --no-download is specified, use empty string for body instead of downloading the body if message has a plaintext and HTML component, only one is returned if prefer_html is true, HTML is returned, otherwise, plaintext /opt/qtemail/bin/email.pl --body-plain [--no-download] [-0] [--folder=FOLDER_NAME] ACCOUNT_NAME UID [UID UID ...] same as --body, but override prefer_html=false, and attempt to convert the result to plaintext if it appears to be HTML (uses /usr/bin/html2text if available, or just strips out the tags) /opt/qtemail/bin/email.pl --body-html [--no-download] [-0] [--folder=FOLDER_NAME] ACCOUNT_NAME UID [UID UID ...] same as --body, but override prefer_html=true /opt/qtemail/bin/email.pl --attachments [--folder=FOLDER_NAME] ACCOUNT_NAME DEST_DIR UID [UID UID ...] download the body of the indicated message(s) and save any attachments to DEST_DIR if body is cached, skip download /opt/qtemail/bin/email.pl --cache-all-bodies ACCOUNT_NAME FOLDER_NAME attempt to download the body of all uncached bodies /opt/qtemail/bin/email.pl --print [--folder=FOLDER_NAME] [ACCOUNT_NAME ACCOUNT_NAME ...] format and print cached unread message headers and bodies fetches bodies like "/opt/qtemail/bin/email.pl --body-plain --no-download", similarly converting HTML to plaintext formats whitespace in bodies, compressing multiple empty lines to a max of 2, and prepending every line with 2 spaces /opt/qtemail/bin/email.pl --summary [--folder=FOLDER_NAME] [ACCOUNT_NAME ACCOUNT_NAME ...] format and print cached unread message headers /opt/qtemail/bin/email.pl --status-line [ACCOUNT_NAME ACCOUNT_NAME ...] {cached in ~/.cache/email/status-line when ~/.cache/email/unread-counts or error files change} does not fetch anything, merely reads ~/.cache/email/unread-counts format and print ~/.cache/email/unread-counts the string is a space-separated list of the first character of each account name followed by the integer count no newline character is printed if the count is zero for a given account, it is omitted if accounts are specified, all but those are omitted e.g.: A3 G6 /opt/qtemail/bin/email.pl --status-short [ACCOUNT_NAME ACCOUNT_NAME ...] {cached in ~/.cache/email/status-short when ~/.cache/email/unread-counts or error files change} does not fetch anything, merely reads ~/.cache/email/unread-counts format and print ~/.cache/email/unread-counts if accounts are specified, all but those are omitted omits accounts with unread-count of 0 the string is two lines, each always containing exactly three characters no line can be longer than 3, and if it is shorter, it is left-padded with spaces each line ends in a newline character if any account has error, prints: "ERR", "<total>" if any account has more then 99 emails, prints "big", "<total>" if more than two accounts have a positive unread-count, prints: "all", "<total>" if exactly two accounts have a positive unread-count, prints: "<acc><count>", "<acc><count>" if exactly one account has a positive unread-count, prints: "<acc><count>", "" otherwise, prints: "", "" <total> = total of all unread counts if less than 1000, or '!!!' otherwise <acc> = first character of a given account name <count> = unread count for the indicated account /opt/qtemail/bin/email.pl --has-error [ACCOUNT_NAME ACCOUNT_NAME ...] checks if ~/.cache/email/ACCOUNT_NAME/error exists print "yes" and exit with zero exit code if it does otherwise, print "no" and exit with non-zero exit code /opt/qtemail/bin/email.pl --has-new-unread [ACCOUNT_NAME ACCOUNT_NAME ...] checks for any NEW unread emails, in any account {UIDs in ~/.cache/email/ACCOUNT_NAME/new-unread} if accounts are specified, all but those are ignored print "yes" and exit with zero exit code if there are new unread emails otherwise, print "no" and exit with non-zero exit code /opt/qtemail/bin/email.pl --has-unread [ACCOUNT_NAME ACCOUNT_NAME ...] checks for any unread emails, in any account {UIDs in ~/.cache/email/ACCOUNT_NAME/unread} if accounts are specified, all but those are ignored print "yes" and exit with zero exit code if there are unread emails otherwise, print "no" and exit with non-zero exit code /opt/qtemail/bin/email.pl --read-config ACCOUNT_NAME reads ~/.secrets for each line of the form "email.ACCOUNT_NAME.KEY\s*=\s*VAL" print KEY=VAL /opt/qtemail/bin/email.pl --write-config ACCOUNT_NAME KEY=VAL [KEY=VAL KEY=VAL] modifies ~/.secrets for each KEY/VAL pair: removes any line that matches "email.ACCOUNT_NAME.KEY\s*=" adds a line at the end "email.ACCOUNT_NAME.KEY = VAL" /opt/qtemail/bin/email.pl --read-options reads ~/.secrets for each line of the form "email.KEY\s*=\s*VAL" print KEY=VAL /opt/qtemail/bin/email.pl --write-options KEY=VAL [KEY=VAL KEY=VAL] reads ~/.secrets for each line of the form "email.KEY\s*=\s*VAL" print KEY=VAL /opt/qtemail/bin/email.pl --read-config-schema print the allowed keys and descriptions for account config entries formatted, one per line, like this: <KEY_NAME>=<DESC> KEY_NAME: one of: user password server port smtp_server smtp_port ssl inbox sent folders count_include skip body_cache_mode prefer_html new_unread_cmd update_interval refresh_interval filters DESC: text description /opt/qtemail/bin/email.pl --read-options-schema print the allowed keys and descriptions for global option entries formatted, one per line, like this: <KEY_NAME>=<DESC> KEY_NAME: one of: update_cmd encrypt_cmd decrypt_cmd DESC: text description ===== email-search.pl ===== /opt/qtemail/bin/email-search.pl --updatedb ACCOUNT_NAME FOLDER_NAME LIMIT create sqlite database if it doesnt exist updates database incrementally LIMIT maximum number of headers to update at once can be 'all' or a positive integer /opt/qtemail/bin/email-search.pl --format WORD [WORD WORD..] parse and format QUERY="WORD WORD WORD" for testing /opt/qtemail/bin/email-search.pl --search [OPTIONS] ACCOUNT_NAME WORD [WORD WORD..] print UIDs of emails matching QUERY="WORD WORD WORD .." OPTIONS: --folder=FOLDER_NAME use FOLDER_NAME instead of "inbox" --minuid=MIN_UID ignore all UIDs below MIN_UID --maxuid=MAX_UID ignore all UIDs above MAX_UID --limit=UID_LIMIT ignore all except the last UID_LIMIT UIDs SEARCH FORMAT: -all words separated by spaces must match one of subject/date/from/to/cc/bcc apple banana => emails where subject/from/to/cc/bcc/date matches both 'apple' AND 'banana' -specify an individual field of subject/date/from/to/cc/bcc with a '~' from~mary => emails from 'mary' -negate a header field query with '!~' instead of '~' from!~mary => emails from everyone EXCEPT 'mary' -specify that the body must match with a '~' body~bus (can be abbreviated with just 'b', e.g.: "b~bus") => emails where the cached body matches 'bus' -negate a body query with '!~' instead of '~' body!~bus => emails where the cached body does NOT match 'bus' -specify disjunction with '++' from~mary ++ from~john ++ from~sue => emails from 'mary' PLUS emails from 'john' PLUS emails from 'sue' -group space or ++ separated words with parentheses (from~mary a) ++ (from~john b) => emails from 'mary' that match 'a' PLUS emails from 'john' that match 'b' -parentheses can nest arbitrarily deep (a ++ (b (c ++ d))) => emails that match 'a', PLUS emails that match 'b' AND match 'c' or 'd' -special characters can be escaped with backslash subject\~fish\ table => emails where subject/from/to/cc/bcc/date matches 'subject~fish table' -doublequoted strings are treated as words "this is a (single ++ w~ord)" => emails where subject/from/to/cc/bcc/date matches 'this is a (single ++ w~ord)' GRAMMAR: QUERY = <LIST_AND> | <LIST_OR> | <HEADER_QUERY> | <NEGATED_HEADER_QUERY> | <SIMPLE_HEADER_QUERY> | <BODY_QUERY> | <NEGATED_BODY_QUERY> | (<QUERY>) return emails that match this QUERY LIST_AND = <QUERY> <QUERY> return only emails that match both QUERYs LIST_OR = <QUERY> ++ <QUERY> return emails that match either QUERY or both HEADER_QUERY = <HEADER_FIELD>~<PATTERN> return emails where the indicated header field matches the pattern NEGATED_HEADER_QUERY = <HEADER_FIELD>!~<PATTERN> return emails where the indicated header field does NOT match the pattern SIMPLE_HEADER_QUERY = <PATTERN> return emails with at least one header field that matches the pattern BODY_QUERY = body~<PATTERN> return emails where the body matches the pattern NEGATED_BODY_QUERY = body!~<PATTERN> return emails where the body does NOT match the pattern HEADER_FIELD = subject | from | to | cc | bcc | date | body restricts the fields that PATTERN can match PATTERN = <string> | <string>"<string>"<string> can be any string, supports doublequote quoting and backslash escaping EXAMPLES: ===== from~mary [from] LIKE mary ===== mary smith ALL( |--[to cc bcc from subject] LIKE mary |--[to cc bcc from subject] LIKE smith ) ===== ((a b) ++ (c d) ++ (e f)) ANY( |--ALL( | |--[to cc bcc from subject] LIKE a | |--[to cc bcc from subject] LIKE b | ) |--ALL( | |--[to cc bcc from subject] LIKE c | |--[to cc bcc from subject] LIKE d | ) |--ALL( | |--[to cc bcc from subject] LIKE e | |--[to cc bcc from subject] LIKE f | ) ) ===== subject~b ++ "subject~b" ANY( |--[subject] LIKE b |--[to cc bcc from subject] LIKE subject~b ) ===== from!~bob ++ subject!~math ANY( |--[from] NOT LIKE bob |--[subject] NOT LIKE math ) ===== "a ++ b" [to cc bcc from subject] LIKE a ++ b ===== ===== email-gui.py ===== /opt/qtemail/bin/email-gui.py [OPTS] OPTS: --page=[account|header|config|send|folder|body] start on the indicated page --account=ACCOUNT_NAME default the account to ACCOUNT_NAME {only useful with --page} --folder=FOLDER_NAME default the folder to ACCOUNT_NAME {only useful with --page} --uid=UID default the message to UID {only useful with --page}
About
No description, website, or topics provided.
Resources
Stars
Watchers
Forks
Packages 0
No packages published