imap uid + cli getById
This commit is contained in:
parent
800ce9f013
commit
bc7a1a2876
10
impra/cli.py
10
impra/cli.py
|
@ -243,13 +243,19 @@ you can remove index but all presents files on the box %s will be unrecoverable
|
|||
sys.exit(1)
|
||||
|
||||
if o.list :
|
||||
|
||||
if impst.index != None:
|
||||
impst.index.print(True,'-'*120+'\n -- INDEX '+impst.rootBox+'\n'+'-'*120)
|
||||
elif o.add :
|
||||
impst.addFile(o.add[0],o.add[1],o.user,o.category)
|
||||
elif o.get :
|
||||
print(o.get)
|
||||
impst.getFile(o.get)
|
||||
elif o.get_by_id :
|
||||
print(o.get_by_id)
|
||||
label = impst.index.searchById(o.get_by_id)
|
||||
if label !=None :
|
||||
impst.getFile(label)
|
||||
else: print(o.get_by_id+' a is not valid id')
|
||||
|
||||
elif o.search :
|
||||
print(o.search)
|
||||
elif o.remove :
|
||||
|
|
108
impra/core.py
108
impra/core.py
|
@ -42,7 +42,7 @@ from os import remove, urandom, sep
|
|||
from os.path import abspath, dirname, join, realpath, basename, getsize, splitext
|
||||
from re import split as regsplit
|
||||
from impra.imap import ImapHelper, ImapConfig
|
||||
from impra.util import __CALLER__, Rsa, RuTime, Noiser, Randomiz, RuTime, hash_sha256, formatBytes, randomFrom, bstr, quote_escape, stack, run
|
||||
from impra.util import __CALLER__, Rsa, RuTime, Noiser, Randomiz, RuTime, hash_sha256, formatBytes, randomFrom, bstr, quote_escape, stack, run, file_exists, get_file_content
|
||||
|
||||
DEBUG = True
|
||||
|
||||
|
@ -205,12 +205,17 @@ class ImpraConf:
|
|||
def get(self, key, section='main', profile=None):
|
||||
""""""
|
||||
if profile == None : profile = self.profile
|
||||
return self.ini.get(key, profile+self.SEP_SECTION+section)
|
||||
v = None
|
||||
if self.ini.has(key,profile+self.SEP_SECTION+section):
|
||||
v = self.ini.get(key, profile+self.SEP_SECTION+section)
|
||||
return v
|
||||
|
||||
def set(self, key, value, section='main', profile=None):
|
||||
""""""
|
||||
if profile == None : profile = self.profile
|
||||
return self.ini.set(key, value, profile+self.SEP_SECTION+section)
|
||||
v = self.ini.set(key, value, profile+self.SEP_SECTION+section)
|
||||
self.ini.write()
|
||||
return v
|
||||
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -235,7 +240,7 @@ class ImpraIndex:
|
|||
"""Separator used for internal key such categories"""
|
||||
|
||||
|
||||
def __init__(self, rsa, encdata='', dicCategory={}):
|
||||
def __init__(self, rsa, encdata='', dicCategory={}, id=0):
|
||||
"""Initialize the index with rsa and encoded data
|
||||
|
||||
:Parameters:
|
||||
|
@ -247,7 +252,7 @@ class ImpraIndex:
|
|||
"""
|
||||
self.rsa = rsa
|
||||
self.dic = {}
|
||||
self.id = 0
|
||||
self.id = id
|
||||
if encdata =='' : data = encdata
|
||||
else : data = self.rsa.decrypt(encdata)
|
||||
data = data.replace(self.QUOTE_REPL, '\'')
|
||||
|
@ -255,11 +260,10 @@ class ImpraIndex:
|
|||
l = regsplit(self.SEP_ITEM,ld[0])
|
||||
for row in l:
|
||||
d = regsplit(self.SEP_TOKEN,row)
|
||||
del d[7:]
|
||||
# key : count, hash, ext, usr, cat
|
||||
if len(d)>4 and d!='':
|
||||
d.append(self.id)
|
||||
if len(d)>5 and d!='':
|
||||
self.dic[d[1]] = d
|
||||
self.id += 1
|
||||
if len(ld)>1:
|
||||
l = regsplit(self.SEP_ITEM,ld[1].lstrip('\n'))
|
||||
for row in l:
|
||||
|
@ -288,7 +292,16 @@ class ImpraIndex:
|
|||
"""Search the corresponding label in the index"""
|
||||
return self.dic.get(label)
|
||||
|
||||
def toString(self, withoutCatg=False):
|
||||
def searchById(self,sid):
|
||||
"""Search the corresponding label in the index"""
|
||||
rt = RuTime(eval(__CALLER__()))
|
||||
l = None
|
||||
r = [v for i, v in enumerate(self.dic) if self.dic[v][6] == str(sid)]
|
||||
if len(r)>0: l = r[0]
|
||||
rt.stop()
|
||||
return l
|
||||
|
||||
def toString(self, withoutCatg=False, idFirst=False):
|
||||
"""Make a string representation of the index as it was store on the server"""
|
||||
data = cdata = ''
|
||||
for k in sorted(self.dic):
|
||||
|
@ -296,7 +309,11 @@ class ImpraIndex:
|
|||
if k[0]==self.SEP_KEY_INTERN and len(k)>1:
|
||||
cdata += k+'='+v+self.SEP_ITEM
|
||||
else :
|
||||
if not idFirst :
|
||||
for i in v: data += str(i)+self.SEP_TOKEN
|
||||
else :
|
||||
data += str(v[6]).rjust(1+ceil(len(str(v[6]))/10),' ')+' '
|
||||
for i in v[:-1]: data += str(i)+self.SEP_TOKEN
|
||||
data = data.rstrip(self.SEP_TOKEN)+self.SEP_ITEM
|
||||
if not withoutCatg :
|
||||
data += self.SEP_CATEGORY+'\n'+cdata
|
||||
|
@ -308,13 +325,10 @@ class ImpraIndex:
|
|||
|
||||
def print(self,withoutCatg=False, header=''):
|
||||
"""Print index content as formated bloc"""
|
||||
data = self.toString(withoutCatg).split(';')
|
||||
i = 0
|
||||
data = self.toString(withoutCatg,True).split(';')
|
||||
print(header)
|
||||
for row in data:
|
||||
if row.rstrip('\n') != '':
|
||||
print(str(i).rjust(1+ceil(len(data)/10),' ')+' - '+row)
|
||||
i += 1
|
||||
if row.rstrip('\n') != '': print(row)
|
||||
|
||||
|
||||
|
||||
|
@ -329,6 +343,7 @@ class ImpraStorage:
|
|||
if wkdir == None : wkdir = abspath(join(dirname( __file__ ), '..', 'wk'))
|
||||
self.wkdir = wkdir
|
||||
self.conf = conf
|
||||
self.pathInd = dirname(self.conf.ini.path)+sep+'.index'
|
||||
self.rootBox = self.conf.get('box','imap')
|
||||
iconf = ImapConfig(self.conf.get('host','imap'), self.conf.get('port','imap'), self.conf.get('user', 'imap'), self.conf.get('pass', 'imap'))
|
||||
self.ih = ImapHelper(iconf,self.rootBox)
|
||||
|
@ -342,8 +357,7 @@ class ImpraStorage:
|
|||
def _getIdIndex(self):
|
||||
""""""
|
||||
mid = None
|
||||
status, resp = self.ih.srv.search(None, '(SUBJECT "%s")' % self.mb.getHashName('index'))
|
||||
ids = [m for m in resp[0].split()]
|
||||
ids = self.ih.searchBySubject(self.mb.getHashName('index'),True)
|
||||
if len(ids) > 0 and int(ids[0]) >= 0 :
|
||||
mid = ids[len(ids)-1]
|
||||
for i in ids:
|
||||
|
@ -357,20 +371,40 @@ class ImpraStorage:
|
|||
ids = [m for m in resp[0].split()]
|
||||
return ids
|
||||
|
||||
def getIndex(self):
|
||||
def _getCryptIndex(self):
|
||||
""""""
|
||||
index = None
|
||||
self._getIdIndex()
|
||||
encData = ''
|
||||
if not self.idx : self._getIdIndex()
|
||||
if self.idx :
|
||||
msgIndex = self.ih.email(self.idx)
|
||||
for i in self.delids : self.ih.delete(i)
|
||||
msgIndex = self.ih.email(self.idx, True)
|
||||
if msgIndex != None :
|
||||
for part in msgIndex.walk():
|
||||
ms = part.get_payload(decode=True)
|
||||
encData = str(ms,'utf-8')
|
||||
else :
|
||||
return encData
|
||||
|
||||
def getIndex(self):
|
||||
""""""
|
||||
rt = RuTime(eval(__CALLER__()))
|
||||
index = None
|
||||
encData = ''
|
||||
self.ih.deleteBin()
|
||||
index = ImpraIndex(self.rsa, encData, {'catg':self.conf.get('types','catg')})
|
||||
uid = self.conf.get('uid' ,'index')
|
||||
date = self.conf.get('date','index')
|
||||
nid = self.conf.get('nid' ,'index')
|
||||
if nid==None : nid = 0
|
||||
if uid !=None : print(uid+' - '+date+' - ['+(str(nid))+']')
|
||||
self._getIdIndex()
|
||||
if self.idx :
|
||||
# getFromFile
|
||||
if int(self.idx) == int(uid) and file_exists(self.pathInd):
|
||||
encData = get_file_content(self.pathInd)
|
||||
print('cache')
|
||||
else:
|
||||
encData = self._getCryptIndex()
|
||||
with open(self.pathInd, mode='w', encoding='utf-8') as o:
|
||||
o.write(encData)
|
||||
index = ImpraIndex(self.rsa, encData, {'catg':self.conf.get('types','catg')}, int(nid))
|
||||
rt.stop()
|
||||
return index
|
||||
|
||||
def removeIndex(self):
|
||||
|
@ -384,11 +418,18 @@ class ImpraStorage:
|
|||
global DEBUG
|
||||
rt = RuTime(eval(__CALLER__()))
|
||||
if self.idx != None :
|
||||
self.ih.delete(self.idx)
|
||||
self.ih.delete(self.idx, True)
|
||||
for i in self.delids : self.ih.delete(i, True)
|
||||
encData = self.index.encrypt()
|
||||
msgIndex = self.mb.buildIndex(encData)
|
||||
if DEBUG: print(msgIndex.as_string())
|
||||
self.ih.send(msgIndex.as_string(), self.rootBox)
|
||||
ids = self.ih.send(msgIndex.as_string(), self.rootBox)
|
||||
date = self.ih.headerField('date', ids[1], True)
|
||||
self.conf.set('uid',ids[1],'index')
|
||||
self.conf.set('date',date,'index')
|
||||
with open(self.pathInd, mode='w', encoding='utf-8') as o:
|
||||
o.write(encData)
|
||||
self.ih.deleteBin()
|
||||
#self.index = self.getIndex()
|
||||
rt.stop()
|
||||
|
||||
|
@ -414,6 +455,7 @@ class ImpraStorage:
|
|||
remove(self.fsplit.DIR_OUTBOX+row[1]+'.ipr')
|
||||
self.index.add(hlst['head'][3],hlst['head'][0],hlst['head'][1],ext,self.mb.getHashName(usr),catg)
|
||||
self.saveIndex()
|
||||
self.conf.set('nid', str(self.index.id),'index')
|
||||
else :
|
||||
raise Exception(label + ' already exist on server')
|
||||
except Exception as e :
|
||||
|
@ -424,8 +466,11 @@ class ImpraStorage:
|
|||
""""""
|
||||
global DEBUG
|
||||
rt = RuTime(eval(__CALLER__('"%s"' % label)))
|
||||
if label==None :
|
||||
print(str(label)+' unexist')
|
||||
else :
|
||||
key = self.index.search(label)
|
||||
if key!=None :
|
||||
if label!=None and key!=None:
|
||||
ck = ConfigKey(key[0])
|
||||
count = int(key[2])
|
||||
hlst = ck.getHashList(label,count,True)
|
||||
|
@ -442,11 +487,14 @@ class ImpraStorage:
|
|||
print(v)
|
||||
self.fsplit.deployFile(hlst, key[3])
|
||||
else :
|
||||
raise Exception(label+' is private')
|
||||
#raise Exception(label+' is private')
|
||||
print(label+' is private')
|
||||
else :
|
||||
raise Exception(label+' : invalid count parts '+str(len(ids))+'/'+str(count))
|
||||
#raise Exception(label+' : invalid count parts '+str(len(ids))+'/'+str(count))
|
||||
print(label+' : invalid count parts '+str(len(ids))+'/'+str(count))
|
||||
else:
|
||||
raise Exception(label+' not on the server')
|
||||
#raise Exception(str(label)+' not on the server')
|
||||
print(str(label)+' not on the server')
|
||||
rt.stop()
|
||||
|
||||
def clean(self):
|
||||
|
|
|
@ -188,19 +188,23 @@ class ImapHelper:
|
|||
|
||||
def countSeen(self, box='INBOX'):
|
||||
""""""
|
||||
s = self.status()
|
||||
s = self.status(box)
|
||||
return s['MESSAGES']-s['UNSEEN']
|
||||
|
||||
def countUnseen(self, box='INBOX'):
|
||||
""""""
|
||||
return self.status()['UNSEEN']
|
||||
return self.status(box)['UNSEEN']
|
||||
|
||||
def countMsg(self, box='INBOX'):
|
||||
""""""
|
||||
return self.status()['MESSAGES']
|
||||
return self.status(box)['MESSAGES']
|
||||
|
||||
def _ids(self, box='INBOX', search='ALL', charset=None):
|
||||
def _ids(self, box='INBOX', search='ALL', charset=None, byUid=False):
|
||||
""""""
|
||||
status, resp = self.srv.select(box)
|
||||
if status == self.KO :
|
||||
self.createBox(box)
|
||||
self.srv.select(box)
|
||||
status, resp = self.srv.search(charset, '(%s)' % search)
|
||||
return split(' ',bstr(resp[self.K_HEAD]))
|
||||
|
||||
|
@ -239,19 +243,54 @@ class ImapHelper:
|
|||
rt.stop()
|
||||
return status==self.OK
|
||||
|
||||
def subject(self, mid):
|
||||
def subject(self, mid, byUid=False):
|
||||
""""""
|
||||
status, resp = self.srv.fetch(mid, '(body[header.fields (subject)])')
|
||||
status, resp = self.fetch(mid, '(UID BODY[HEADER.FIELDS (SUBJECT)])', byUid)
|
||||
subject = decode_header(str(resp[self.K_HEAD][1][9:-4], 'utf-8'))[0]
|
||||
s = subject[0]
|
||||
if subject[1] :
|
||||
s = str(s,subject[1])
|
||||
return s
|
||||
|
||||
def email(self, mid):
|
||||
def search(self, query, byUid=False):
|
||||
if byUid :
|
||||
status, resp = self.srv.uid('search', None, query)
|
||||
else :
|
||||
status, resp = self.srv.search(None, query)
|
||||
ids = [m for m in resp[0].split()]
|
||||
return ids
|
||||
|
||||
def searchBySubject(self, subject, byUid=False):
|
||||
return self.search('(SUBJECT "%s")' % subject, byUid)
|
||||
|
||||
def getUid(self, mid):
|
||||
""""""
|
||||
status, resp = self.srv.fetch(mid,'(UID RFC822)')
|
||||
value = ''
|
||||
status, resp = self.srv.fetch(mid, '(UID)')
|
||||
if status==self.OK :
|
||||
value = resp[0][len(str(mid))+3:-1]
|
||||
return value
|
||||
|
||||
def fetch(self, mid, query, byUid=False):
|
||||
""""""
|
||||
if not byUid :
|
||||
status, resp = self.srv.fetch(mid, query)
|
||||
else:
|
||||
status, resp = self.srv.uid('fetch', mid, query)
|
||||
return status, resp
|
||||
|
||||
def headerField(self, field, mid, byUid=False):
|
||||
""""""
|
||||
value = ''
|
||||
status, resp = self.fetch(mid, '(UID BODY[HEADER.FIELDS (%s)])' % field.upper(), byUid)
|
||||
if status==self.OK and resp[0]!=None:
|
||||
value = str(resp[0][1][len(field)+2:-4],'utf-8')
|
||||
return value
|
||||
|
||||
def email(self, mid, byUid=False):
|
||||
""""""
|
||||
status, resp = self.fetch(mid,'(UID RFC822)', byUid)
|
||||
if status == self.OK and resp[0]!=None:
|
||||
msg = message_from_bytes(resp[0][1])
|
||||
else :
|
||||
msg = None
|
||||
|
@ -261,20 +300,30 @@ class ImapHelper:
|
|||
""""""
|
||||
rt = RuTime(eval(__CALLER__()))
|
||||
self.srv.select(self.BOX_BIN)
|
||||
ids = self._ids(self.BOX_BIN)
|
||||
if len(ids) > 0 and ids[0]!='':
|
||||
ids = self.search('ALL',True)
|
||||
if len(ids) > 0 and ids[0]!='' and ids[0]!=None:
|
||||
#print(str(ids[0],'utf-8').split())
|
||||
for mid in ids:
|
||||
print('deleting msg '+mid)
|
||||
status, resp = self.srv.store(mid, '+FLAGS', '\\Deleted')
|
||||
print('deleting msg '+str(mid))
|
||||
#~ uid = bytes(mid)
|
||||
#~ print(type(mid))
|
||||
#~ print(mid)
|
||||
#status, resp = self.srv.store(mid, '+FLAGS', '\\Deleted')
|
||||
status, resp = self.srv.uid('store', mid, '+FLAGS', '\\Deleted' )
|
||||
print(status)
|
||||
print(resp)
|
||||
self.srv.expunge()
|
||||
self.srv.select(self.rootBox)
|
||||
rt.stop()
|
||||
|
||||
def delete(self, mid):
|
||||
def delete(self, mid, byUid=False):
|
||||
""""""
|
||||
rt = RuTime(eval(__CALLER__('%i' % int(mid))))
|
||||
status = None
|
||||
if int(mid) > 0 :
|
||||
if byUid:
|
||||
status, resp = self.srv.uid( 'store', mid, '+FLAGS', '\\Deleted' )
|
||||
else :
|
||||
status, resp = self.srv.store(mid, '+FLAGS', '\\Deleted')
|
||||
self.srv.expunge()
|
||||
rt.stop()
|
||||
|
@ -298,8 +347,13 @@ class ImapHelper:
|
|||
def send(self, msg, box='INBOX'):
|
||||
""""""
|
||||
rt = RuTime(eval(__CALLER__()))
|
||||
self.srv.append(box, '\Draft', Time2Internaldate(time()), bytes(msg,'utf-8'))
|
||||
mid = None
|
||||
date = Time2Internaldate(time())
|
||||
status, resp = self.srv.append(box, '\Draft', date, bytes(msg,'utf-8'))
|
||||
if status==self.OK:
|
||||
mid = str(resp[0],'utf-8')[11:-11].split(' ')
|
||||
rt.stop()
|
||||
return mid
|
||||
|
||||
if __name__ == '__main__':
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
@ -85,6 +85,15 @@ def get_file_path(val):
|
|||
""""""
|
||||
return abspath(dirname(val))+sep
|
||||
|
||||
def file_exists(path):
|
||||
""""""
|
||||
try:
|
||||
with open(path) as f:
|
||||
exist = True
|
||||
except IOError as e:
|
||||
exist = False
|
||||
return exist
|
||||
|
||||
def formatBytes(b, p=2):
|
||||
"""Give a human representation of bytes size `b`
|
||||
:Returns: `str`
|
||||
|
|
|
@ -27,40 +27,44 @@
|
|||
# along with ImpraStorage. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from impra.core import ImpraConf, ImpraStorage
|
||||
from impra.util import IniFile, Rsa, RuTime
|
||||
from impra.util import IniFile, Rsa, RuTime, get_file_path
|
||||
from impra.cli import Cli
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
rt = RuTime(__name__+'()')
|
||||
conf = ImpraConf(IniFile('./impra.ini'))
|
||||
rsa = Rsa(conf.ini.get('prvKey',conf.profile+'.keys'),conf.ini.get('pubKey',conf.profile+'.keys'))
|
||||
impst = ImpraStorage(rsa, conf)
|
||||
|
||||
print('\n -- INDEX DATA -- ')
|
||||
impst.index.print()
|
||||
Cli(get_file_path(__file__ ))
|
||||
#~ rt = RuTime(__name__+'()')
|
||||
#~ conf = ImpraConf(IniFile('./impra.ini'))
|
||||
#~ rsa = Rsa(conf.ini.get('prvKey',conf.profile+'.keys'),conf.ini.get('pubKey',conf.profile+'.keys'))
|
||||
#~ impst = ImpraStorage(rsa, conf)
|
||||
#~
|
||||
#~ print('\n -- INDEX DATA -- ')
|
||||
#~ impst.index.print()
|
||||
#~ print('-- LIST BOX --')
|
||||
#~ lb = impst.ih.listBox('/')
|
||||
#~ print(lb)
|
||||
|
||||
#print('-- DELETE BIN --')
|
||||
#impst.ih.deleteBin()
|
||||
|
||||
filePath = '/media/Data/dev/big_toph3.jpg'
|
||||
|
||||
lab = 'Meuf\'bonne aussi4'
|
||||
|
||||
print('\n -- ADD FILE -- ')
|
||||
impst.addFile(filePath,lab,conf.ini.get('name',conf.profile+'.infos'),'images')
|
||||
|
||||
print('\n -- GET FILE -- ')
|
||||
impst.getFile(lab)
|
||||
|
||||
print('\n -- INDEX DATA -- ')
|
||||
impst.index.print()
|
||||
|
||||
print('\n -- CLEAN -- ')
|
||||
impst.clean()
|
||||
|
||||
rt.stop()
|
||||
#~
|
||||
#~ #print('-- DELETE BIN --')
|
||||
#~ #impst.ih.deleteBin()
|
||||
#~
|
||||
#~ filePath = '/media/Data/dev/big_toph3.jpg'
|
||||
#~
|
||||
#~ lab = 'Meuf\'bonne aussi4'
|
||||
#~
|
||||
#~ print('\n -- ADD FILE -- ')
|
||||
#~ impst.addFile(filePath,lab,conf.ini.get('name',conf.profile+'.infos'),'images')
|
||||
#~
|
||||
#~ print('\n -- GET FILE -- ')
|
||||
#~ impst.getFile(lab)
|
||||
#~
|
||||
#~ print('\n -- INDEX DATA -- ')
|
||||
#~ impst.index.print()
|
||||
#~
|
||||
#~ print('\n -- CLEAN -- ')
|
||||
#~ impst.clean()
|
||||
#~
|
||||
#~ rt.stop()
|
||||
|
||||
#python -O -m compileall impra/*.py
|
||||
|
|
Loading…
Reference in New Issue
Block a user