kindle manager

This commit is contained in:
gavin
2020-06-07 10:21:02 +08:00
parent 722757dadd
commit 76cc0d8c6d
15 changed files with 1007 additions and 233 deletions

122
kman.py
View File

@@ -9,10 +9,12 @@
import re
import os
import io
import json
import time
import logging
import platform
import subprocess
from collections import defaultdict
# data structure - use dict
@@ -123,7 +125,7 @@ class kMan:
kp = self.get_kindle_path()
if not kp:
s2 = u'Disconnected'
s2 = u'Disconnected ({})'.format(CLIPPATH)
else:
with open(kp+'/system/version.txt' , 'r', encoding='utf8', errors='ignore') as f:
s2 = u'Connected ({}) version {}'.format(kp,f.read().strip())
@@ -189,8 +191,8 @@ class kMan:
# parse #1 line
aus = au.search(authinfo)
bookname = aus.group(1)
author = aus.group(2)
bookname = aus.group(1).strip()
author = aus.group(2).strip()
section[bookname]['author'] = author
section['bookname'] = bookname
@@ -314,6 +316,73 @@ class kMan:
return bks
def get_bookname_num(self,bks):
""" get note number of booknames
Args:
bks: books dict
Return: dict {bookname:num,...}
"""
bksnum = defaultdict(dict)
nu = 0
for kb,vb in bks.items():
bksnum.setdefault(kb, 0)
for ks, vs in vb.copy().items():
if ks in ['author', 'lines']: continue
bksnum[kb] += 1
nu += 1
return [nu, bksnum]
def get_author_num(self,bks):
""" get note number of author
Args:
bks: books dict
Return: dict {bookname:num,...}
"""
bksnum = defaultdict(dict)
nu = 0
for kb,vb in bks.items():
for ks, vs in vb.copy().items():
if ks in ['author', 'lines']: 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
Args:
bks: books dict
info: filter by bookname or author information
tp: type to be filter
0: top/root item clicked
1: bookname item clicked
2: author item clicked
"""
nbks = defaultdict(dict)
# do not filter
if tp==0: nbks = bks
# do filter
for kb, vb in bks.items():
if [info, tp] in ([kb, 1], [vb['author'], 2]):
nbks[kb] = vb
seclist = []
idx = 0
for kb, vb in nbks.items():
for ks,vs in vb.items():
if ks in ['author', 'lines']: continue
tm = self.format_time(' '.join([vs['day'],vs['week'], \
vs['meridiem'],vs['time']]))
tp = '标注' if vs['type']=='HL' else '笔记'
seclist.append((vs['content'],tp,kb,vb['author'],vs['position'],tm))
idx += 1
return seclist
def add_note_to_highlight(self,bks):
""" append note content to corresponding highlight
and remove NT sections
@@ -349,7 +418,8 @@ class kMan:
'TITLE'
'AUTHOR'
'CONTENT'
Return: search clipping content
Return:
[number of result , result dict]
"""
nbks = defaultdict(dict)
nu = 0
@@ -405,37 +475,58 @@ class kMan:
else ("ls /Volumes/Kindle" if os.name=='posix' else '')
# not test for windows & linux
with os.popen(cmd) as s:
r = s.read()
with subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, \
stderr=subprocess.PIPE, bufsize=-1) as s:
stream_stdout = io.TextIOWrapper(s.stdout, encoding='utf-8')
stream_stderr = io.TextIOWrapper(s.stderr, encoding='utf-8')
sout = str(stream_stdout.read())
#serr = str(stream_stderr.read())
#if sout: print('stdout {}'.format(sout))
#if serr: print('stderr {}'.format(serr))
if os.name == 'nt': # windows
for d in r.split('\n'):
for d in sout.split('\n'):
if 'Kindle' in d: return d.split('\s+')[0]
elif os.name == 'posix': # mac os
if r: return('/Volumes/Kindle')
if sout: return('/Volumes/Kindle')
else:
pass
"""
# will print error information on stdout
with os.popen(cmd) as s:
sout = s.read()
if os.name == 'nt': # windows
for d in sout.split('\n'):
if 'Kindle' in d: return d.split('\s+')[0]
elif os.name == 'posix': # mac os
if sout: return('/Volumes/Kindle')
else:
pass
"""
return False
def import_clips(self, tp='local'):
def import_clips(self, fp=CLIPPATH):
"""import clips from local file or kindle
4 lines for each section seperated with '======='
so read 4 lines before '======='
Args: tp: 'local' local clipping file
'kindle' kindle clipping file
Args: fp - file path
Return: 0 - want to import kindle but kindle is not connected
books dict
"""
# check kindle by user just call get_kindle_path()
"""
if tp=='kindle':
kp = get_kindle_path()
if not kp: return 0
else: path = kp
else:
path = CLIPPATH
path = fn
"""
# loop to fill books dict
with open(path, 'r', encoding='utf8', errors='ignore') as f:
with open(fp, 'r', encoding='utf8', errors='ignore') as f:
bks = defaultdict(dict)
secd = defaultdict(dict)
sidx = 0
@@ -490,7 +581,7 @@ class kMan:
if __name__=='__main__':
#books = defaultdict(dict)
km = kMan()
books = km.import_clips('local')
books = km.import_clips()
# remove duplication
km.drop_duplicate(books)
@@ -503,6 +594,9 @@ if __name__=='__main__':
searchnote = km.search_clip(books, '巴曙松', 'ALL', 'AUTHOR')
if searchnote[0] > 0: km.format_out(searchnote[1], 'searchauthor', ft='MD')
print(km.get_bookname_num(books))
print(km.get_author_num(books))
# add note content to hightlight, then delete note
km.add_note_to_highlight(books)