kindle manager
This commit is contained in:
89
kman.py
89
kman.py
@@ -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))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user