Example #1
0
 def __init__(self, ih, conf, wkdir='./', emit=None):
     """"""
     self.idx     = None
     self.index   = None
     self.emit    = emit
     self.delids  = []
     self.ih      = ih
     self.conf    = conf
     self.pathIdx = wkdir+'.index.'+self.conf.profile+Kirmah.EXT
     self.mb      = MailBuilder(self.conf.get('salt','keys'))
     self.rootBox = self.conf.get('box','imap')
     self.get()
Example #2
0
class IndexUpdater:
    """"""
    @Log(Const.LOG_BUILD)
    def __init__(self, ih, conf, wkdir='./', emit=None):
        """"""
        self.idx     = None
        self.index   = None
        self.emit    = emit
        self.delids  = []
        self.ih      = ih
        self.conf    = conf
        self.pathIdx = wkdir+'.index.'+self.conf.profile+Kirmah.EXT
        self.mb      = MailBuilder(self.conf.get('salt','keys'))
        self.rootBox = self.conf.get('box','imap')
        self.get()


    @Log(Const.LOG_DEBUG)
    def _getId(self, notAssign=False):
        """"""
        idx = None
        ids = self.ih.searchBySubject(self.mb.getHashName('index'),True)
        if len(ids) > 0 and int(ids[0]) >= 0 :
            idx = ids[-1]
            if not notAssign: self.delids = ids[:-1]
        if not notAssign:
            self.idx = idx
        return idx 


    @Log()
    def get(self, forceRefresh=False):
        """"""
        self.switchFileAccount(self.conf.profile)
        index   = None
        uid     = self.conf.get('uid'  ,'index')
        date    = self.conf.get('date' ,'index')
        tstamp  = self.conf.get('time' ,'index')
        refresh = forceRefresh        
        delta   = None if tstamp is None else Sys.datetime.now() - Sys.datetime.strptime(tstamp[:-7], '%Y-%m-%d %H:%M:%S')
        if not refresh and tstamp is not None and delta < Sys.timedelta(minutes = 3) :
            # getFromFile            
            if uid != None and Io.file_exists(self.pathIdx): # int(self.idx) == int(uid) 
                self.idx = uid
                Sys.pwlog([(' Get index from cache '  , Const.CLZ_7),
                           ('('                       , Const.CLZ_0),
                           (str(int(self.idx))        , Const.CLZ_2),
                           (')'                       , Const.CLZ_0, True)])
            else: refresh = True
        else: refresh = True
        self.irefresh = refresh
        if refresh :
            Sys.pwlog([(' Checking index...', Const.CLZ_0, True)])
            self._getId()
            if self.idx :
                if int(self.idx) != int(uid) or not Io.file_exists(self.pathIdx):
                    Sys.pwlog([(' Refreshing index (local:', Const.CLZ_0),
                               (str(int(uid))              , Const.CLZ_2),
                               (' / remote:'               , Const.CLZ_0),
                               (str(int(self.idx))         , Const.CLZ_1),
                               (')'                        , Const.CLZ_0, True)])
                    
                    date = self.ih.headerField(self.idx, 'date', True)
                    self.conf.sets((['uid'  , str(int(self.idx))     , 'index'],
                                    ['date' , date                   , 'index'],
                                    ['time' , str(Sys.datetime.now()), 'index']))
                    self._saveLocalIndex()
                else :
                    Sys.pwlog([(' Get index from cache '  , Const.CLZ_7),
                               ('('                       , Const.CLZ_0),
                               (str(int(self.idx))        , Const.CLZ_2),
                               (')'                       , Const.CLZ_0, True)])
                self.conf.set('time',str(Sys.datetime.now()),'index')
        self.build()        


    @Log()
    def build(self):
        Sys.pwlog([(' Reading index, please wait...', Const.CLZ_7, True)])
        self.index = ImpraIndex(self.conf.get('key','keys'), self.pathIdx, self.getIndexDefaultCatg(), self.getAccountList())
        defUsers   = self.conf.get('users','catg')
        if not ImpraIndex.SEP_KEY_INTERN+'users' in self.index.dic:
            self.index.dic[ImpraIndex.SEP_KEY_INTERN+'users'] = {}
        for k in self.index.dic[ImpraIndex.SEP_KEY_INTERN+'users']:
            if self.index.dic[ImpraIndex.SEP_KEY_INTERN+'users'][k] not in [ i.strip() for i in defUsers.split(',')]:
                self.conf.set('users',defUsers+', '+self.index.dic[ImpraIndex.SEP_KEY_INTERN+'users'][k],'catg')


    @Log(Const.LOG_DEBUG)
    def getAccountList(self):
        l  = {}
        pl = self.conf.get('multi','imap')
        if pl is not None and len(pl)>0 :
            pl = pl.split(',')
            if len(pl) > 0:
                if not self.conf.profile in pl:
                    pl.append(self.conf.profile)
        else : pl = [self.conf.profile]
        for p in pl : l[p] = self.conf.get('user','imap',p)
        return l
        

    @Log(Const.LOG_DEBUG)
    def getIndexDefaultCatg(self):
        """"""
        usrName  = self.conf.get('name','infos')
        defUsers = self.conf.get('users','catg').split(',')
        dic      = {'catg':self.conf.get('types','catg'), 'users':{ ('%s' % self.mb.getHashName('all')) : 'all', ('%s' % self.mb.getHashName(usrName)) : usrName}}
        for u in defUsers :
           dic['users'][('%s' % self.mb.getHashName(u.strip()))] = u.strip()
        return dic


    @Log(Const.LOG_DEBUG)
    def _saveLocalIndex(self):
        """"""
        if not self.idx : self._getId()
        if self.idx :
            msg     = self.ih.getEmail(self.idx, True)
            content = b''
            for part in msg.walk():
                content += part.get_payload(decode=True)
            Io.set_data(self.pathIdx, a2b_base64(content), True)
        

    @Log()
    def removeLocal(self):
        """"""
        self.conf.rem('*','index')
        self.conf.save()
        self.idx = None
        Io.removeFile(self.pathIdx)


    @Log()
    def remove(self):
        """"""
        self._getId()
        try:
            if self.idx!= None : self.delids.append(Io.bytes(self.idx))
            self.ih.delete(self.delids, True)
            self.idx = None
        except Exception as e :
            Sys.dprint('error : ')
            Sys.dprint(e)
            
        self.ih.clearTrash()
        self.removeLocal()
        

    @Log(Const.LOG_APP)
    def update(self):
        """"""
        self.switchFileAccount(self.conf.profile)
        try:
            if self.idx != None :
                if not isinstance(self.idx,bytes):
                    self.idx = Io.bytes(self.idx)                
                self.delids.append(self.idx)
        except Exception as e :
            Sys.dprint('error : ')
            Sys.dprint(e)   

        self.index.fixDuplicateIds()
        #~ self.index.fixAccount('gmail5')
        self.index.encrypt()
        msgIndex    = self.mb.buildIndex(self.pathIdx)
        _, self.idx = self.ih.send(msgIndex.as_string(), self.rootBox)
        date        = self.ih.headerField(self.idx, 'date', True)
        self.conf.sets((['uid'  , self.idx              , 'index'],
                       ['date' , date                   , 'index'],
                       ['time' , str(Sys.datetime.now()), 'index']))
        
        Sys.pwlog([(' Index updated ('  , Const.CLZ_0),
                   (str(int(self.idx))  , Const.CLZ_2),
                   (') '                , Const.CLZ_0),
                   (str(date)           , Const.CLZ_7, True)])
        
        try :
            self.ih.delete(self.delids, True)       
        except :
            Sys.dprint('error : ')
            Sys.dprint(e)
        self.ih.clearTrash()
        return True

    @Log()
    def switchFileAccount(self, profile=None, force=False):
        """"""
        pl = self.conf.get('multi','imap')
        if pl is not None and len(pl)>0 :
            pl = pl.split(',')
            if len(pl) > 0:
                if not self.conf.profile in pl:
                    pl.append(self.conf.profile)
                iconf   = self.ih.conf
                account = self.conf.get('user','imap',profile)
                if True or iconf.user != account :
                    # reinit
                    iconf.user = None
                    try :
                        if profile is None : profile = self.index.getLightestAccount(pl)                        
                        if profile in pl :
                            iconf.user = self.conf.get('user','imap',profile)
                            iconf.pwd  = self.conf.get('pass','imap',profile)
                            iconf.host = self.conf.get('host','imap',profile)
                            iconf.port = self.conf.get('port','imap',profile)
                        self.ih.switchAccount(iconf, self.rootBox, force)
                    except BadLoginException as e:
                        Sys.dprint('Error : ')
                        Sys.dprint(e)
                        Sys.dprint('check your connection or your imap config for profile '+profile)
        if profile is None: profile = self.conf.profile
        return profile