-
-
Save julianandrews/e7f7d4024b1589ba4fed to your computer and use it in GitHub Desktop.
#!/usr/bin/python3 | |
import argparse | |
import getpass | |
import keyring | |
import requests | |
import sys | |
import xml.etree.ElementTree | |
SERVICE_NAME = 'gmail-count' | |
def get_url(email_address): | |
localpart, _, domain = email_address.rpartition('@') | |
if domain == 'gmail.com': | |
return 'https://mail.google.com/mail/feed/atom/' | |
else: | |
return 'https://mail.google.com/a/%s/feed/atom/' % domain | |
def get_count_from_xml(xml_string): | |
tree = xml.etree.ElementTree.fromstring(xml_string) | |
node = tree.find('{http://purl.org/atom/ns#}fullcount') | |
return node.text | |
def get_mail_count(email_address): | |
url = get_url(email_address) | |
password = keyring.get_password(SERVICE_NAME, email_address) | |
if password is None: | |
print("No password found for '%s'." % email_address, file=sys.stderr) | |
return | |
auth = requests.auth.HTTPBasicAuth(email_address, password) | |
response = requests.get(url, auth=auth) | |
if response.status_code == 200: | |
try: | |
return get_count_from_xml(response.content) | |
except xml.etree.ElementTree.ParseError: | |
print("Failed to parse XML:\n%s" % xml_string, file=sys.stderr) | |
else: | |
print("Request failed:\n%s" % response.content, file=sys.stderr) | |
def parse_args(): | |
parser = argparse.ArgumentParser(description='Check gmail message count.') | |
parser.add_argument( | |
'-s', | |
'--set-pass', | |
dest='set_pass', | |
action='store_true', | |
default=False, | |
help='set the password for email_address', | |
) | |
parser.add_argument( | |
'-d', | |
'--delete-pass', | |
dest='delete_pass', | |
action='store_true', | |
default=False, | |
help='delete the password for email_address' | |
) | |
parser.add_argument('email_address', help='Email Address') | |
return parser.parse_args() | |
if __name__ == '__main__': | |
args = parse_args() | |
if args.set_pass and args.delete_pass: | |
raise parser.error('-s and -d are mutually exclusive') | |
elif args.set_pass: | |
password = getpass.getpass() | |
keyring.set_password(SERVICE_NAME, args.email_address, password) | |
elif args.delete_pass: | |
keyring.delete_password(SERVICE_NAME, args.email_address) | |
else: | |
print(get_mail_count(args.email_address) or '?') |
Here's a shell script suitable for use with i3blocks:
#!/bin/sh
[ "$BLOCK_BUTTON" = 1 ] && xdg-open https://inbox.google.com
$email='my_email@gmail.com'
full_text=$(~/bin/gmail-count "$email")
case $full_text in
''|*[!0-9]*) color=\#FF0000 ;;
0) color=\#888888 ;;
*) color=\#00FF00 ;;
esac
echo "$full_text"
echo "$short_text"
echo "$color"
Configure with something like:
[mail]
label=✉
command=~/.config/i3/gmail-status.sh
interval=60
Man that's wayyyy too complicated and only works with gmail.
I've written a very small and useable script in bash:
https://github.com/Anachron/i3blocks/blob/master/blocks/mail
I've switched to xmonad. Here's a script that works for xmobar:
#!/bin/sh
email='my_email@gmail.com'
full_text=$(~/bin/gmail-count "$email")
case $full_text in
''|*[!0-9]*) color=\#FF0000 ;;
0) color=\#888888 ;;
*) color=\#00FF00 ;;
esac
echo "<action=\`xdg-open https://inbox.google.com\`><fc=$color>✉ $full_text</fc></action>"
@Anachron: Your script really doesn't do what I need from a security point of view. It stores the password in plaintext and requires using lower security methods for access (I'm using 2-factor authentication and an app specific password).
Take out my code for using the system keyring and my argument parsing to make a nice clean interface and you'll find that my script is pretty short.
Updated to work with python 3. I also switched from urllib2
to requests
, which is cleaner, and removed the verbose
flag in favor of just printing to stderr. This way I can still output ?
for failed attempts so that the output for xmobar etc. is reasonable, but the script reliably provides helpful error messages when used from the command line.
I've gone ahead and made a proper repo for this script:
I was fiddling with it compulsively, and it seemed worth the trouble:
Use verbose mode if you want more than minimal output; this script is designed by default to suppress all excess output for convenient use with i3status.
The script, requires the python keyring module and a compatible system keyring. It would be pretty easy to modify it to accept a password via the command-line, but I'll leave that particular sin for someone else to commit.