mass commit

fixed imap idle implementation (reuse open imap connections and don't poll unaffected accounts)
reconnect if a connection has been lost (e.g. after standby)
moved connection check from startup script to mailnag.py
removed unused/unnecessary code
refactoring, fixed exception handling
This commit is contained in:
Patrick Ulbrich
2012-01-02 20:33:42 +01:00
parent 3c365bb22e
commit 6d68a191c9
10 changed files with 313 additions and 238 deletions

View File

@@ -3,7 +3,7 @@
#
# account.py
#
# Copyright 2011 Patrick Ulbrich <zulu99@gmx.net>
# Copyright 2011, 2012 Patrick Ulbrich <zulu99@gmx.net>
# Copyright 2011 Ralf Hersel <ralf.hersel@gmx.net>
#
# This program is free software; you can redistribute it and/or modify
@@ -22,7 +22,6 @@
# MA 02110-1301, USA.
#
import time
import poplib
import daemon.imaplib2 as imaplib
from common.i18n import _
@@ -42,7 +41,7 @@ account_defaults = {
class Account:
def __init__(self, enabled = False, name = _('Unnamed'), user = '', \
password = '', server = '', port = '', ssl = True, imap = False, idle = False, folder = '' ):
self.enabled = enabled # bool
self.name = name
self.user = user
@@ -53,55 +52,72 @@ class Account:
self.imap = imap # bool
self.idle = idle # bool
self.folder = folder
self._conn = None
def get_connection(self): # get email server connection
def get_connection(self, use_existing = False): # get email server connection
if self.imap:
try:
srv = self._get_IMAP_connection()
conn = self._get_IMAP_connection(use_existing)
except:
print "Error: Cannot connect to IMAP account: %s. " % self.server
srv = None
conn = None
else:
try:
srv = self._get_POP3_connection()
conn = self._get_POP3_connection(use_existing)
except:
print "Error: Cannot connect to POP account: %s. " % self.server
srv = None
conn = None
return srv # server object
def _get_IMAP_connection(self):
if self.ssl:
if self.port == '':
srv = imaplib.IMAP4_SSL(self.server)
else:
srv = imaplib.IMAP4_SSL(self.server, self.port)
else:
if self.port == '':
srv = imaplib.IMAP4(self.server)
else:
srv = imaplib.IMAP4(self.server, self.port)
srv.login(self.user, self.password)
return srv
return conn
def _get_POP3_connection(self):
def get_id(self):
# TODO : this id is not really unique...
return str(hash(self.user + self.server))
def _get_IMAP_connection(self, use_existing):
# try to reuse existing connection
if use_existing and (self._conn != None) and \
(self._conn.state != imaplib.LOGOUT) and (not self._conn.Terminate):
return self._conn
if self.ssl:
if self.port == '':
srv = poplib.POP3_SSL(self.server)
self._conn = imaplib.IMAP4_SSL(self.server)
else:
srv = poplib.POP3_SSL(self.server, self.port)
self._conn = imaplib.IMAP4_SSL(self.server, self.port)
else:
if self.port == '':
srv = poplib.POP3(self.server)
self._conn = imaplib.IMAP4(self.server)
else:
srv = poplib.POP3(self.server, self.port)
self._conn = imaplib.IMAP4(self.server, self.port)
srv.getwelcome()
srv.user(self.user)
srv.pass_(self.password)
return srv
self._conn.login(self.user, self.password)
return self._conn
def _get_POP3_connection(self, use_existing):
# try to reuse existing connection
if use_existing and (self._conn != None) and ('sock' in self._conn.__dict__):
return self._conn
if self.ssl:
if self.port == '':
self._conn = poplib.POP3_SSL(self.server)
else:
self._conn = poplib.POP3_SSL(self.server, self.port)
else:
if self.port == '':
self._conn = poplib.POP3(self.server)
else:
self._conn = poplib.POP3(self.server, self.port)
self._conn.getwelcome()
self._conn.user(self.user)
self._conn.pass_(self.password)
return self._conn

View File

@@ -3,7 +3,7 @@
#
# mails.py
#
# Copyright 2011 Patrick Ulbrich <zulu99@gmx.net>
# Copyright 2011, 2012 Patrick Ulbrich <zulu99@gmx.net>
# Copyright 2007 Marco Ferragina <marco.ferragina@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
@@ -27,6 +27,7 @@ from gi.repository import Gst, Gio
import threading
import os
import time
import urllib2
PACKAGE_NAME = "mailnag"
@@ -68,6 +69,14 @@ def get_default_mail_reader():
return mail_reader
def is_online(): # check for internet connection
try:
urllib2.urlopen("http://www.google.com/")
return True
except:
return False
class _GstPlayThread(threading.Thread):
def __init__(self, ply):
self.ply = ply

View File

@@ -3,8 +3,8 @@
#
# idler.py
#
# Copyright 2011, 2012 Patrick Ulbrich <zulu99@gmx.net>
# Copyright 2011 Leighton Earl <leighton.earl@gmx.com>
# Copyright 2011 Patrick Ulbrich <zulu99@gmx.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -23,13 +23,22 @@
#
import threading
from daemon.imaplib2 import AUTH
class Idler(object):
def __init__(self, conn, sync_callback):
def __init__(self, account, sync_callback):
self._thread = threading.Thread(target=self._idle)
self._conn = conn
self._event = threading.Event()
self._sync_callback = sync_callback
self._account = account
self._conn = account.get_connection(use_existing = True) # connection has been opened in mailnag.py already (immediate check)
if self._conn == None:
raise Exception("Failed to establish a connection for account '%s'" % account.name)
# Need to get out of AUTH mode of fresh connections.
if self._conn.state == AUTH:
self._select(self._conn, account.folder)
def run(self):
@@ -41,8 +50,11 @@ class Idler(object):
self._event.set()
self._thread.join()
self._conn.close()
self._conn.logout()
try:
self._conn.close()
self._conn.logout()
except:
pass
print "Idler closed"
@@ -55,11 +67,19 @@ class Idler(object):
self._needsync = False
def callback(args):
if (args[2] != None) and (args[2][0] is self._conn.abort):
# connection has been reset by provider -> reopen
print "Idler thread for account '%s' reconnected" % self._account.name
self._conn = self._account.get_connection(use_existing = False)
self._select(self._conn, self._account.folder)
if not self._event.isSet():
self._needsync = True
self._event.set()
self._conn.idle(callback=callback)
# register idle callback that is called whenever an idle event arrives (new mail / mail deleted).
# the callback is called after 10 minutes at the latest. gmail sends keepalive events every 5 minutes.
self._conn.idle(callback = callback, timeout = 60 * 10)
# Waits for event to be set
self._event.wait()
@@ -67,6 +87,12 @@ class Idler(object):
# If the event is set due to idle sync
if self._needsync:
self._event.clear()
self._sync_callback()
self._sync_callback(self._account)
def _select(self, conn, folder):
folder = folder.strip()
if len(folder) > 0:
conn.select(folder)
else:
conn.select("INBOX")

View File

@@ -3,8 +3,8 @@
#
# idlers.py
#
# Copyright 2011, 2012 Patrick Ulbrich <zulu99@gmx.net>
# Copyright 2011 Leighton Earl <leighton.earl@gmx.com>
# Copyright 2011 Patrick Ulbrich <zulu99@gmx.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -35,35 +35,14 @@ class Idlers:
for acc in self._accounts:
if acc.imap and acc.idle:
try:
self._new_idler(acc)
except:
pass
idler = Idler(acc, self._sync_callback)
idler.run()
self._idlerlist.append(idler)
except Exception as ex:
print "Error: Failed to create an idler thread for account '%s'" % acc.name
def dispose(self):
for idler in self._idlerlist:
idler.dispose()
def _new_idler(self, account):
server = account.get_connection()
if server == None:
return
# Need to get out of AUTH mode.
if len(account.folder) > 0:
server.select(account.folder)
else:
server.select("INBOX")
try:
tmp = server.search(None, 'UNSEEN') # ALL or UNSEEN
except:
server.select('INBOX', readonly=True) # If search fails select INBOX and try again
tmp = server.search(None, 'UNSEEN') # ALL or UNSEEN
idler = Idler(server, self._sync_callback)
idler.run()
self._idlerlist.append(idler)

View File

@@ -3,7 +3,7 @@
#
# mail.py
#
# Copyright 2011 Patrick Ulbrich <zulu99@gmx.net>
# Copyright 2011, 2012 Patrick Ulbrich <zulu99@gmx.net>
# Copyright 2011 Ralf Hersel <ralf.hersel@gmx.net>
#
# This program is free software; you can redistribute it and/or modify
@@ -23,10 +23,10 @@
#
class Mail:
def __init__(self, seconds, subject, sender, datetime, id, provider):
def __init__(self, seconds, subject, sender, datetime, id, account_id):
self.seconds = seconds
self.subject = subject
self.sender = sender
self.datetime = datetime
self.id = id
self.provider = provider
self.account_id = account_id

View File

@@ -3,7 +3,7 @@
#
# mailchecker.py
#
# Copyright 2011 Patrick Ulbrich <zulu99@gmx.net>
# Copyright 2011, 2012 Patrick Ulbrich <zulu99@gmx.net>
# Copyright 2011 Ralf Hersel <ralf.hersel@gmx.net>
#
# This program is free software; you can redistribute it and/or modify
@@ -29,18 +29,19 @@ import subprocess
import os
import time
from common.utils import get_data_file, gstplay, get_default_mail_reader
from common.utils import get_data_file, gstplay, is_online, get_default_mail_reader
from common.i18n import _
from daemon.reminder import Reminder
from daemon.mails import Mails
from daemon.mailsyncer import MailSyncer
from daemon.pid import Pid
class MailChecker:
def __init__(self, cfg, accounts):
def __init__(self, cfg):
self.MAIL_LIST_LIMIT = 10 # prevent flooding of the messaging tray
self.firstcheck = True; # first check after startup
self.mailcheck_lock = threading.Lock()
self.mails = Mails(cfg, accounts)
self.mail_list = []
self.mailsyncer = MailSyncer(cfg)
self.reminder = Reminder()
self.pid = Pid()
self.cfg = cfg
@@ -50,14 +51,18 @@ class MailChecker:
self.reminder.load()
Notify.init(cfg.get('general', 'messagetray_label')) # initialize Notification
def check(self):
def check(self, accounts):
with self.mailcheck_lock:
print 'Checking email accounts at:', time.asctime()
self.pid.kill() # kill all zombies
self.mail_list = self.mails.get_mail('desc') # get all mails from all inboxes
if not is_online():
print 'Error: No internet connection'
return
self.mail_list = self.mailsyncer.sync(accounts)
unseen_mails = []
new_mails = []
@@ -80,7 +85,7 @@ class MailChecker:
script_data = str(script_data_mailcount) + script_data
if len(self.mail_list) == 0:
# no mails (e.g. email client has been launched) -> close notifications
# no mails (e.g. email client has been launched) -> close notifications
for n in self.notifications.itervalues():
n.close()
self.notifications = {}
@@ -94,14 +99,13 @@ class MailChecker:
gstplay(get_data_file(self.cfg.get('general', 'soundfile')))
self.reminder.save(self.mail_list)
self.__run_user_scripts("on_mail_check", script_data) # process user scripts
sys.stdout.flush() # write stdout to log file
self.firstcheck = False
self.__run_user_scripts("on_mail_check", script_data) # process user scripts
sys.stdout.flush() # write stdout to log file
return True
return
def __notify_summary(self, unseen_mails):
summary = ""
body = ""
@@ -162,22 +166,7 @@ class MailChecker:
# so remove its reference
del self.notifications[user_data[1]]
def clear(self):
with self.mailcheck_lock:
# mark all mails to seen
for mail in self.mail_list:
self.reminder.set_to_seen(mail.id)
self.reminder.save(self.mail_list)
# close all notifications
for n in self.notifications.itervalues():
n.close()
self.notifications = {}
self.mail_list = []
def __run_user_scripts(self, event, data):
if event == "on_mail_check":
if self.cfg.get('script', 'script0_enabled') == '1':

View File

@@ -3,7 +3,7 @@
#
# mails.py
#
# Copyright 2011 Patrick Ulbrich <zulu99@gmx.net>
# Copyright 2011, 2012 Patrick Ulbrich <zulu99@gmx.net>
# Copyright 2011 Leighton Earl <leighton.earl@gmx.com>
# Copyright 2011 Ralf Hersel <ralf.hersel@gmx.net>
#
@@ -24,7 +24,6 @@
#
import time
import urllib2
import sys
import email
@@ -38,100 +37,93 @@ class Mails:
self.accounts = accounts
def get_mail(self, sort_order):
def get_mail(self, sort_order = None):
mail_list = [] # initialize list of mails
mail_ids = [] # initialize list of mail ids
if not self.__is_online(): # check internet connection
return mail_list
filter_enabled = bool(int(self.cfg.get('filter', 'filter_enabled'))) # get filter switch
for acc in self.accounts:
srv = acc.get_connection() # get server connection for this account
srv = acc.get_connection(use_existing = True) # get server connection for this account
if srv == None:
continue # continue with next account if server is empty
elif acc.imap: # IMAP
folder_list = acc.folder.split(',') # make a list of folders
mail_count = 0 # reset email counter
if folder_list[0] == '':
folder_list = ['INBOX']
for folder in folder_list:
tmp = folder.strip()
srv.select(tmp, readonly=True) # select IMAP folder
folder = acc.folder.strip()
if len(folder) == 0:
folder = "INBOX"
srv.select(folder, readonly=True) # select IMAP folder
try:
status, data = srv.search(None, 'UNSEEN') # ALL or UNSEEN
except:
print "The folder:", folder, "does not exist, using INBOX instead"
try:
srv.select('INBOX', readonly=True) # If search fails select INBOX and try again
status, data = srv.search(None, 'UNSEEN') # ALL or UNSEEN
except:
print "The folder:", tmp, "does not exist, using INBOX instead"
try:
srv.select('INBOX', readonly=True) # If search fails select INBOX and try again
status, data = srv.search(None, 'UNSEEN') # ALL or UNSEEN
except:
print "INBOX Could not be found", sys.exc_info()[0]
print "INBOX Could not be found", sys.exc_info()[0]
if status != 'OK' or None in [d for d in data]:
print "Folder", folder, "in status", status, "| Data:", data, "\n"
continue # Bugfix LP-735071
for num in data[0].split():
typ, msg_data = srv.fetch(num, '(BODY.PEEK[HEADER])') # header only (without setting READ flag)
for response_part in msg_data:
if isinstance(response_part, tuple):
if status != 'OK' or None in [d for d in data]:
print "Folder", folder, "in status", status, "| Data:", data, "\n"
continue # Bugfix LP-735071
for num in data[0].split():
typ, msg_data = srv.fetch(num, '(BODY.PEEK[HEADER])') # header only (without setting READ flag)
for response_part in msg_data:
if isinstance(response_part, tuple):
try:
msg = email.message_from_string(response_part[1])
except:
print "Could not get IMAP message." # debug
continue
try:
try:
msg = email.message_from_string(response_part[1])
except:
print "Could not get IMAP message." # debug
continue
sender = self.__format_header('sender', msg['From']) # get sender and format it
except KeyError:
print "KeyError exception for key 'From' in message." # debug
sender = self.__format_header('sender', msg['from'])
except:
print "Could not get sender from IMAP message." # debug
sender = "Error in sender"
try:
try:
try:
sender = self.__format_header('sender', msg['From']) # get sender and format it
except KeyError:
print "KeyError exception for key 'From' in message." # debug
sender = self.__format_header('sender', msg['from'])
except:
print "Could not get sender from IMAP message." # debug
sender = "Error in sender"
datetime, seconds = self.__format_header('date', msg['Date']) # get date and format it
except KeyError:
print "KeyError exception for key 'Date' in message." # debug
datetime, seconds = self.__format_header('date', msg['date'])
except:
print "Could not get date from IMAP message." # debug
datetime = time.strftime('%Y.%m.%d %X') # take current time as "2010.12.31 13:57:04"
seconds = time.time() # take current time as seconds
try:
try:
try:
datetime, seconds = self.__format_header('date', msg['Date']) # get date and format it
except KeyError:
print "KeyError exception for key 'Date' in message." # debug
datetime, seconds = self.__format_header('date', msg['date'])
except:
print "Could not get date from IMAP message." # debug
datetime = time.strftime('%Y.%m.%d %X') # take current time as "2010.12.31 13:57:04"
seconds = time.time() # take current time as seconds
try:
try:
subject = self.__format_header('subject', msg['Subject']) # get subject and format it
except KeyError:
print "KeyError exception for key 'Subject' in message." # debug
subject = self.__format_header('subject', msg['subject'])
except:
print "Could not get subject from IMAP message." # debug
subject = _('No subject')
try:
id = msg['Message-Id']
except:
print "Could not get id from IMAP message." # debug
id = None # prepare emergency
if id == None or id == '':
id = str(hash(subject)) # create emergency id
if id not in mail_ids: # prevent duplicates caused by Gmail labels
if not (filter_enabled and self.__in_filter(sender + subject)): # check filter
mail_list.append(Mail(seconds, subject, \
sender, datetime, id, acc.name))
mail_count += 1 # increment mail counter for this IMAP folder
mail_ids.append(id) # add id to list
subject = self.__format_header('subject', msg['Subject']) # get subject and format it
except KeyError:
print "KeyError exception for key 'Subject' in message." # debug
subject = self.__format_header('subject', msg['subject'])
except:
print "Could not get subject from IMAP message." # debug
subject = _('No subject')
try:
id = msg['Message-Id']
except:
print "Could not get id from IMAP message." # debug
id = None
if id == None or id == '':
id = str(hash(acc.server + acc.user + sender + subject)) # create fallback id
if id not in mail_ids: # prevent duplicates caused by Gmail labels
if not (filter_enabled and self.__in_filter(sender + subject)): # check filter
mail_list.append(Mail(seconds, subject, \
sender, datetime, id, acc.get_id()))
mail_ids.append(id) # add id to list
acc.mail_count = mail_count # store number of emails per account
srv.close()
srv.logout()
# don't close IMAP idle connections
if not acc.idle:
srv.close()
srv.logout()
else: # POP
mail_total = len(srv.list()[1]) # number of mails on the server
mail_count = 0 # reset number of relevant mails
for i in range(1, mail_total+1): # for each mail
try:
message = srv.top(i, 0)[1] # header plus first 0 lines from body
@@ -176,31 +168,25 @@ class Mails:
uidl = srv.uidl(i) # get id
except:
print "Could not get id from POP message." # debug
uidl = None # prepare emergency
uidl = None
if uidl == None or uidl == '':
uidl = str(hash(subject)) # create emergency id
id = str(hash(acc.server + acc.user + sender + subject)) # create fallback id
else:
id = acc.user + uidl.split(' ')[2] # create unique id
id = acc.user + uidl.split(' ')[2] # create unique id
if not (filter_enabled and self.__in_filter(sender + subject)): # check filter
mail_list.append(Mail(seconds, subject, sender, \
datetime, id, acc.name))
mail_count += 1 # increment mail counter for this IMAP folder
acc.mail_count = mail_count # store number of emails per account
datetime, id, acc.get_id()))
srv.quit() # disconnect from Email-Server
mail_list = self.__sort_mails(mail_list, sort_order) # sort mails
if (sort_order != None):
mail_list = self.sort_mails(mail_list, sort_order) # sort mails
sys.stdout.flush() # write stdout to log file
return mail_list
def __is_online(self): # check for internet connection
try:
urllib2.urlopen("http://www.google.com/")
return True
except:
return False
def __in_filter(self, sendersubject): # check if filter appears in sendersubject
status = False
filter_text = self.cfg.get('filter', 'filter_text')
@@ -217,7 +203,8 @@ class Mails:
return status
def __sort_mails(self, mail_list, sort_order): # sort mail list
@staticmethod
def sort_mails(mail_list, sort_order): # sort mail list
sort_list = []
for mail in mail_list:
sort_list.append([mail.seconds, mail]) # extract seconds from mail instance

View File

@@ -0,0 +1,76 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# mailsyncer.py
#
# Copyright 2012 Patrick Ulbrich <zulu99@gmx.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
from daemon.mails import Mails
class MailSyncer:
def __init__(self, cfg):
self._cfg = cfg
self._mails_by_account = {}
self._mail_list = []
def sync(self, accounts):
needs_rebuild = False
# get mails from given accounts
rcv_lst = Mails(self._cfg, accounts).get_mail()
# group received mails by account
tmp = {}
for acc in accounts:
tmp[acc.get_id()] = {}
for mail in rcv_lst:
tmp[mail.account_id][mail.id] = mail
# compare current mails against received mails
# and remove those that are gone (probably opened in mail client).
for acc_id in self._mails_by_account.iterkeys():
if acc_id in tmp:
del_ids = []
for mail_id in self._mails_by_account[acc_id].iterkeys():
if not (mail_id in tmp[acc_id]):
del_ids.append(mail_id)
needs_rebuild = True
for mail_id in del_ids:
del self._mails_by_account[acc_id][mail_id]
# compare received mails against current mails
# and add new mails.
for acc_id in tmp:
if not (acc_id in self._mails_by_account):
self._mails_by_account[acc_id] = {}
for mail_id in tmp[acc_id]:
if not (mail_id in self._mails_by_account[acc_id]):
self._mails_by_account[acc_id][mail_id] = tmp[acc_id][mail_id]
needs_rebuild = True
# rebuild and sort mail list
if needs_rebuild:
self._mail_list = []
for acc_id in self._mails_by_account:
for mail_id in self._mails_by_account[acc_id]:
self._mail_list.append(self._mails_by_account[acc_id][mail_id])
self._mail_list = Mails.sort_mails(self._mail_list, 'desc')
return self._mail_list

View File

@@ -3,7 +3,7 @@
#
# mailnag.py
#
# Copyright 2011 Patrick Ulbrich <zulu99@gmx.net>
# Copyright 2011, 2012 Patrick Ulbrich <zulu99@gmx.net>
# Copyright 2011 Leighton Earl <leighton.earl@gmx.com>
# Copyright 2011 Ralf Hersel <ralf.hersel@gmx.net>
#
@@ -25,10 +25,11 @@
import os
from gi.repository import GObject, GLib
import time
import signal
from common.config import read_cfg, cfg_exists, cfg_folder
from common.utils import set_procname
from common.utils import set_procname, is_online
from common.accountlist import AccountList
from daemon.mailchecker import MailChecker
from daemon.idlers import Idlers
@@ -91,23 +92,38 @@ def main():
print 'Error: Cannot find configuration file. Please run mailnag_config first.'
exit(1)
if not is_online():
print 'Waiting for internet connection...'
while not is_online():
time.sleep(5)
accounts = AccountList()
accounts.load_from_cfg(cfg, enabled_only = True)
mailchecker = MailChecker(cfg, accounts)
mailchecker = MailChecker(cfg)
# immediate check
mailchecker.check()
# immediate check, check *all* accounts
mailchecker.check(accounts)
idle_accounts = filter(lambda acc: acc.imap and acc.idle, accounts)
non_idle_accounts = filter(lambda acc: (not acc.imap) or (acc.imap and not acc.idle), accounts)
# start polling thread for POP3 accounts and
# IMAP accounts without idle support
if sum(1 for acc in accounts if ((not acc.imap ) or (acc.imap and not acc.idle))) > 0:
if len(non_idle_accounts) > 0:
def poll_func():
mailchecker.check(non_idle_accounts)
return True
check_interval = int(cfg.get('general', 'check_interval'))
GObject.timeout_add_seconds(60 * check_interval, mailchecker.check)
GObject.timeout_add_seconds(60 * check_interval, poll_func)
# start idler threads for IMAP accounts with idle support
if sum(1 for acc in accounts if (acc.imap and acc.idle)) > 0:
idlers = Idlers(accounts, mailchecker.check)
if len(idle_accounts) > 0:
def sync_func(account):
mailchecker.check([account])
idlers = Idlers(idle_accounts, sync_func)
idlers.run()
mainloop = GObject.MainLoop()

41
mailnag
View File

@@ -3,37 +3,14 @@ LIB_DIR=./Mailnag
config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/mailnag"
main()
{
mkdir --parents "$config_dir"
mkdir --parents "$config_dir"
if [ -f "$config_dir/mailnag.pid" ]; then
kill $(cat "$config_dir/mailnag.pid") 2> /dev/null
fi
rm --force "$config_dir/mailnag.log"
cd $(dirname $(readlink -f $0))
python $LIB_DIR/mailnag.py >> "$config_dir/mailnag.log" 2>&1 &
}
check_connection()
{
retries=50
while ! ping -c1 www.google.com 2>/dev/null 1>&2 && [ $retries -gt 0 ] ; do
sleep 5
# ((retries--))
done
if [ $retries -gt 0 ]; then
return 0
else
return 1 # timed out
fi
}
if check_connection; then
main
else
echo "Error: No internet connection."
if [ -f "$config_dir/mailnag.pid" ]; then
kill $(cat "$config_dir/mailnag.pid") 2> /dev/null
fi
rm --force "$config_dir/mailnag.log"
cd $(dirname $(readlink -f $0))
python $LIB_DIR/mailnag.py >> "$config_dir/mailnag.log" 2>&1 &