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