kindle manager

This commit is contained in:
gavin
2020-06-11 17:21:16 +08:00
parent c903004b8f
commit 43c602d8d6
38 changed files with 565 additions and 248 deletions

89
kman.py
View File

@@ -56,6 +56,16 @@ books =
}
'''
'''
# vocab.db -> table: book_info
bookname = {'id':{
'title':'bookname_xxx',
'authors':'xxx'
},}
words = {
"bookname_xxx": {
'''
# modi clippath for different os
SYS = 'WIN' if platform.system()=='Windows' else \
('LINUX' if platform.system()=='LINUX' else 'MAC')
@@ -63,14 +73,14 @@ SYS = 'WIN' if platform.system()=='Windows' else \
# some constants
LASTLINE = '=========='
NTPREF = '--CG注:'
CLIPFN = 'My Clippings.txt'
CLIPPATH = './' # /Volumes/Kindle/documents/My\ Clippings.txt
#CLIPPATH = './tclip.txt'
KINDLEFN = 'My Clippings.txt'
CLIPPATH = './'
OUTPREF = './clip'
DEBUG = 1 # 0 - INFO; 1 - DEBUG
LOG2FILE = 1 # 0 - to stdio; 1 - to file
LOGFILE = 'log'
DELIMITER= '|'
BACKUPFN = './backup/bk.data'
#HEADER = {0:'type',1:'bookname',2:'author',3:'position',4:'date',5:'content'}
# log info
@@ -127,7 +137,7 @@ class kMan:
kp = self.get_kindle_path()
if not kp:
s2 = u'Disconnected ({})'.format(CLIPPATH+CLIPFN)
s2 = u'Disconnected ({})'.format(CLIPPATH+KINDLEFN)
else:
with open(kp+'/system/version.txt' , 'r', encoding='utf8', errors='ignore') as f:
s2 = u'Connected ({}) version {}'.format(kp,f.read().strip())
@@ -246,14 +256,14 @@ class kMan:
for kb,vb in bks.items():
author = vb['author']
for ks, vs in vb.items():
if ks in ['author', 'lines']: continue
if ks == 'author': continue
secs.append(DELIMITER.join([vs['type'],kb,author, \
self.format_time(' '.join([vs['day'],vs['week'],\
vs['meridiem'],vs['time']])),vs['content']]))
return hd+secs
def format_out(self,bks, fnpref, ft='MD'):
def export_notes(self, bks, fnpref, ft='MD'):
"""format output and write to file
markdown format:
TYPE | bookname | author | marktime | content
@@ -299,12 +309,10 @@ class kMan:
"""
[preks,prevs] = ['',{'content':'!#$%^&$%','type':'xx'}]
for kb,vb in bks.items():
bks[kb]['lines'] = 0
# add copy() or throw RuntimeError: dictionary changed size during iteration
# reference - http://www.cocoachina.com/articles/89748
for ks, vs in vb.copy().items():
if ks in ['author', 'lines']: continue
bks[kb]['lines'] += 1
if ks == 'author': continue
if (vs['content'] in prevs['content'] or \
prevs['content'] in vs['content']) and \
prevs['type'] == vs['type']:
@@ -318,20 +326,34 @@ class kMan:
return bks
def get_totalnum_nt(self,bks):
""" get total number of note
Args:
bks: books dict
Return: total number of note
"""
nu = 0
for kb,vb in bks.items():
for ks, vs in vb.copy().items():
if ks == 'author': continue
nu += 1
return nu
def get_bookname_num(self,bks):
""" get note number of booknames
Args:
bks: books dict
Return: dict {bookname:num,...}
Return: [total books, note number of books]
"""
bksnum = defaultdict(dict)
nu = 0
nu = 0 # number of books
for kb,vb in bks.items():
bksnum.setdefault(kb, 0)
nu += 1
for ks, vs in vb.copy().items():
if ks in ['author', 'lines']: continue
if ks == 'author': continue
bksnum[kb] += 1
nu += 1
return [nu, bksnum]
@@ -339,22 +361,23 @@ class kMan:
""" get note number of author
Args:
bks: books dict
Return: dict {bookname:num,...}
Return: [total authors, note number of authors]
"""
bksnum = defaultdict(dict)
nu = 0
nu = 0 # number of authors
for kb,vb in bks.items():
for ks, vs in vb.copy().items():
if ks in ['author', 'lines']: continue
if ks == 'author':
nu += 1
continue
au = vb['author']
bksnum.setdefault(au, 0)
bksnum[au] += 1
nu += 1
return [nu, bksnum]
def filter_clips(self, bks, info=None, tp=0):
""" filter clips
""" filter clips to show the clips in table view
Args:
bks: books dict
info: filter by bookname or author information
@@ -381,14 +404,14 @@ class kMan:
idx = 0
for kb, vb in nbks.items():
for ks,vs in vb.items():
if ks in ['author', 'lines']: continue
if ks == 'author': continue
tm = self.format_time(' '.join([vs['day'],vs['week'], \
vs['meridiem'],vs['time']]))
nttype = '标注' if vs['type']=='HL' else '笔记'
seclist.append([nttype,kb,vb['author'],vs['position'],tm,vs['content']])
idx += 1
return seclist
return [nbks, seclist]
def add_note_to_highlight(self,bks):
""" append note content to corresponding highlight
@@ -402,7 +425,7 @@ class kMan:
[preks,prevs] = ['',{'content':'!#$%^&$%','type':'xx'}]
for kb,vb in bks.items():
for ks,vs in vb.copy().items():
if ks in ['author', 'lines']: continue
if ks == 'author': continue
if [prevs['type'], vs['type']] == ['HL','NT']:
bks[kb][preks]['content'] += str(NTPREF+vs['content'])
bks[kb].pop(ks)
@@ -412,7 +435,7 @@ class kMan:
return bks
def search_clip(self,bks, s, t='ALL', p='ALL'):
def search_clip(self, bks, s, t='ALL', p='ALL'):
"""search clip, searching scope may be title/author/content
Args:
input: bks: books dict
@@ -431,9 +454,9 @@ class kMan:
nbks = defaultdict(dict)
nu = 0
for kb,vb in bks.items():
nbks[kb]['lines'] = 0
num_nt_book = 0
for ks,vs in vb.copy().items():
if ks in ['author', 'lines']:
if ks == 'author':
nbks[kb][ks] = vs
continue
if t in ['ALL', vs['type']]:
@@ -442,9 +465,9 @@ class kMan:
found = re.search(s, scopestr[p])
if found:
nbks[kb][ks] = vs
nbks[kb]['lines'] += 1
num_nt_book += 1
nu += 1
if nbks[kb]['lines']==0:
if num_nt_book==0:
nbks.pop(kb)
return [nu,nbks]
@@ -513,7 +536,7 @@ class kMan:
return False
def import_clips(self, fp=(CLIPPATH+CLIPFN)):
def import_clips(self, fp=(CLIPPATH+KINDLEFN)):
"""import clips from local file or kindle
4 lines for each section seperated with '======='
so read 4 lines before '======='
@@ -583,7 +606,8 @@ class kMan:
self.refleshtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
return bks
return self.drop_duplicate(bks)
if __name__=='__main__':
#books = defaultdict(dict)
@@ -595,11 +619,11 @@ if __name__=='__main__':
# test search note function
searchnote = km.search_clip(books, '三大都市圈', 'ALL', 'CONTENT')
if searchnote[0] > 0: km.format_out(searchnote[1], 'searchcontent', ft='MD')
if searchnote[0] > 0: km.export_notes(searchnote[1], 'searchcontent', ft='MD')
searchnote = km.search_clip(books, '经济', 'ALL', 'TITLE')
if searchnote[0] > 0: km.format_out(searchnote[1], 'searchtitle', ft='MD')
if searchnote[0] > 0: km.export_notes(searchnote[1], 'searchtitle', ft='MD')
searchnote = km.search_clip(books, '巴曙松', 'ALL', 'AUTHOR')
if searchnote[0] > 0: km.format_out(searchnote[1], 'searchauthor', ft='MD')
if searchnote[0] > 0: km.export_notes(searchnote[1], 'searchauthor', ft='MD')
print(km.get_bookname_num(books))
print(km.get_author_num(books))
@@ -612,7 +636,8 @@ if __name__=='__main__':
fw.write(km.dict2json(books))
if km.json2dict('./xx')==books: print( 'test OK')
km.format_out(books, OUTPREF, ft='MD')
km.export_notes(books, OUTPREF, ft='MD')
# print data with json format
logger.debug(json.dumps(books, indent=4, sort_keys=True, ensure_ascii=False))