kindle manager
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -76,9 +76,10 @@ b['1']['2'] = {'3':1} # OK
|
|||||||
- implement table model which inherited from QAbstractTableModel, so
|
- implement table model which inherited from QAbstractTableModel, so
|
||||||
we can use **panda data structure**
|
we can use **panda data structure**
|
||||||
|
|
||||||
## 1.0.5 (20200604)
|
## 1.0.5 (20200613)
|
||||||
### feature
|
### feature
|
||||||
- backup clips after kman closed, check and read backup file when kman started
|
- backup clips after kman closed, check and read backup file when kman started
|
||||||
|
- import words from kindle, export filtered words to MD/CSV
|
||||||
|
|
||||||
## learn lesson
|
## learn lesson
|
||||||
|
|
||||||
|
|||||||
13
export.md
13
export.md
@@ -1,2 +1,11 @@
|
|||||||
TYPE|BOOKNAME|AUTHOR|MARKTIME|CONTENT
|
WORD|BOOKNAME|AUTHOR|CATEGORY|USAGE|TIMESTAMP
|
||||||
--|--|--|--|--
|
--|--|--|--|--|--
|
||||||
|
从而|中国为什么有前途:对外经济关系的战略潜能(第3版)|翟东升|mastered|综合以上分析,我们可以概括出美国建立和维持美元霸权,从而居于世界市场体系中央地位的若干基本条件如下:第一,美国在人才、技术、专利以及研发能力等方面维持优势;第二,对战略性地区(东亚和中东)和战略性资产(能源)的控制力;第三,最初对黄金储备的垄断占有,以及先挂钩后脱钩的把戏;第四,有能力保持全球市场(商品、服务和贸易)的开放性,从而确保美元在全球市场的购买力;第五,发展出广度和深度最佳|2020/03/31 22:37:30
|
||||||
|
当|知乎周刊・新技能get|知乎|mastered|后来我想明白了,既然我无论如何都会后悔,那么—— 当我做出比较小、日常琐碎的决定时,只要确定哪些选项属于最优解,则不管选择最优解中的哪一个,我都能接受。 |2015/09/27 17:47:05
|
||||||
|
当|中国为什么有前途:对外经济关系的战略潜能(第3版)|翟东升|mastered|相反,当一家或者少数几家企业利用自己的某种资源控制了市场上的供给或需求时,即便它们是国有企业,比如电信服务业和早期的汽车制造业,它也会提供质次价高的商品与服务,最终损害消费者利益。|2020/04/02 08:15:35
|
||||||
|
当|苏世民:我的经验与教训(2018读桥水达利欧的原则,2020看黑石苏世民的经验!一本书读懂从白手起家到华尔街新国王的传奇人生)|苏世民|mastered|当然,在那天早上,如果我走出办公室来到莱克星顿大道上,看到的依然会是美国经济在强势增长——商店门庭若市,股市创下历史新高。|2020/04/28 08:15:37
|
||||||
|
当然|中国为什么有前途:对外经济关系的战略潜能(第3版)|翟东升|mastered|当然,这里的外汇储备特指官方外汇储备,而不包括民间和其他政府机构。|2020/04/12 21:47:40
|
||||||
|
管涛|中国为什么有前途:对外经济关系的战略潜能(第3版)|翟东升|mastered|管涛则保持中庸的立场,综合了双方的观点。|2020/04/12 21:25:17
|
||||||
|
鼓励|中国为什么有前途:对外经济关系的战略潜能(第3版)|翟东升|mastered|表7-1 中国各地方政府的本地企业国际直接投资鼓励措施5 为了推动我国企业的跨国经营,中国政府正在努力营造一个包括资金使用、信贷保险、外汇管理、财务税收、服务中心等方面的纵向服务体系,每年还根据|2020/04/13 18:12:03
|
||||||
|
如|庆余年(精校版)|猫腻|mastered|他没有想到海棠也会有如此胡闹的一面,也没有想到她做起事情来,竟是这样的大胆决断,这种赌性竟是比自己也差不了多少。 |2020/02/21 10:04:42
|
||||||
|
如|中国为什么有前途:对外经济关系的战略潜能(第3版)|翟东升|mastered|如2008年9月中钢集团敌意收购澳大利亚中西部公司98.52%的股权,到后来发现中西部公司的矿山根本无法开采和利用,造成国有资产的巨大损失。|2020/04/14 12:51:44
|
||||||
|
|||||||
87
kman.py
87
kman.py
@@ -226,8 +226,8 @@ class kMan:
|
|||||||
|
|
||||||
return ymd+tm
|
return ymd+tm
|
||||||
|
|
||||||
def format_data(self,bks, ft='MD'):
|
def format_note_data(self, bks, ft='MD'):
|
||||||
""" format data for MD & CSV
|
""" format notes data for MD & CSV
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
bks: books dict
|
bks: books dict
|
||||||
@@ -255,6 +255,39 @@ class kMan:
|
|||||||
|
|
||||||
return hd+secs
|
return hd+secs
|
||||||
|
|
||||||
|
def format_word_data(self, wdata, flist, ft='MD'):
|
||||||
|
""" format words data for MD & CSV
|
||||||
|
|
||||||
|
Args:
|
||||||
|
wdata: words data [bookinfo, words, lookups]
|
||||||
|
flist: list to be formatted
|
||||||
|
ft: can be 'MD'/'CSV'
|
||||||
|
|
||||||
|
Return:
|
||||||
|
list [header, content]
|
||||||
|
header and content are lists
|
||||||
|
"""
|
||||||
|
[bookinfo, words, lookups] = wdata
|
||||||
|
hd =[] # header
|
||||||
|
secs =[] # content
|
||||||
|
DELIMITER = '|' if ft=='MD' else ','
|
||||||
|
|
||||||
|
hd.append(DELIMITER.join(['WORD','BOOKNAME','AUTHOR','CATEGORY','USAGE','TIMESTAMP']))
|
||||||
|
if ft=='MD':
|
||||||
|
hd.append(DELIMITER.join(['--' for i in range(6)]))
|
||||||
|
|
||||||
|
for frow in flist:
|
||||||
|
[fword,fbookname,fauthor,fcategory]=frow
|
||||||
|
for lrow in lookups:
|
||||||
|
lbookname = bookinfo[lrow[2]]['bookname']
|
||||||
|
lauthor = bookinfo[lrow[2]]['author']
|
||||||
|
[lusage,ltimestamp] = lrow[4:6]
|
||||||
|
if words[lrow[1]]['word']==fword:
|
||||||
|
secs.append(DELIMITER.join(
|
||||||
|
[fword,lbookname,lauthor,fcategory,lusage,ltimestamp]))
|
||||||
|
|
||||||
|
return hd+secs
|
||||||
|
|
||||||
def export_notes(self, bks, fnpref, ft='MD'):
|
def export_notes(self, bks, fnpref, ft='MD'):
|
||||||
"""format output and write to file
|
"""format output and write to file
|
||||||
markdown format:
|
markdown format:
|
||||||
@@ -282,12 +315,46 @@ class kMan:
|
|||||||
if ft=='JSON':
|
if ft=='JSON':
|
||||||
fw.write(json.dumps(bks, indent=4, sort_keys=True, ensure_ascii=False))
|
fw.write(json.dumps(bks, indent=4, sort_keys=True, ensure_ascii=False))
|
||||||
elif ft in ['MD','CSV']:
|
elif ft in ['MD','CSV']:
|
||||||
for s in self.format_data(bks, ft):
|
for s in self.format_note_data(bks, ft):
|
||||||
fw.write(s)
|
fw.write(s)
|
||||||
fw.write('\n')
|
fw.write('\n')
|
||||||
else:
|
else:
|
||||||
fw.write(json.dumps(bks)) # only for load back
|
fw.write(json.dumps(bks)) # only for load back
|
||||||
|
|
||||||
|
# no good! books & words operation need to be abstracted
|
||||||
|
def export_words(self, wdata, flist, fnpref, ft='MD'):
|
||||||
|
"""format output and write to file
|
||||||
|
markdown format:
|
||||||
|
TYPE | bookname | author | marktime | content
|
||||||
|
--|--|--|--|--
|
||||||
|
xx|xx|xx|xx|xx
|
||||||
|
|
||||||
|
CSV format:
|
||||||
|
TYPE,bookname,author,marktime,content
|
||||||
|
xx,xx,xx,xx,xx
|
||||||
|
|
||||||
|
marktime: 20200403 PM 3:0:3 星期五
|
||||||
|
|
||||||
|
Args:
|
||||||
|
bks: books dict
|
||||||
|
f: can be 'MD'/'JSON'/'CSV'
|
||||||
|
|
||||||
|
Returns: special format of 'bks' dict
|
||||||
|
"""
|
||||||
|
|
||||||
|
suff = {'MD':'.md','CSV':'.csv','JSON':'.json'}
|
||||||
|
op = fnpref+suff[ft]
|
||||||
|
|
||||||
|
with open(op, 'w', encoding='utf8', errors='ignore') as fw:
|
||||||
|
if ft=='JSON':
|
||||||
|
fw.write(json.dumps(flist, indent=4, sort_keys=True, ensure_ascii=False))
|
||||||
|
elif ft in ['MD','CSV']:
|
||||||
|
for s in self.format_word_data(wdata, flist, ft):
|
||||||
|
fw.write(s)
|
||||||
|
fw.write('\n')
|
||||||
|
else:
|
||||||
|
fw.write(json.dumps(flist)) # only for load back
|
||||||
|
|
||||||
def drop_duplicate(self,bks):
|
def drop_duplicate(self,bks):
|
||||||
""" drop duplicated section
|
""" drop duplicated section
|
||||||
|
|
||||||
@@ -653,7 +720,7 @@ class kMan:
|
|||||||
lookups.append([row[0],row[1],row[2],row[4],row[5],mtime])
|
lookups.append([row[0],row[1],row[2],row[4],row[5],mtime])
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print('sql failure {}'.format(e))
|
print('SQL Failure: {}'.format(e))
|
||||||
finally:
|
finally:
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
@@ -671,8 +738,8 @@ class kMan:
|
|||||||
1: word item clicked
|
1: word item clicked
|
||||||
Return: [filtted words_data, word_list]
|
Return: [filtted words_data, word_list]
|
||||||
word_list:
|
word_list:
|
||||||
[[Bookname,Author,word,category],
|
[[Word,Bookname,Author,category],
|
||||||
[Bookname,Author,word,status],
|
[word,Bookname,Author,category],
|
||||||
....]
|
....]
|
||||||
"""
|
"""
|
||||||
[bookinfo, words, lookups] = wdata
|
[bookinfo, words, lookups] = wdata
|
||||||
@@ -681,12 +748,12 @@ class kMan:
|
|||||||
if tp == 0:
|
if tp == 0:
|
||||||
for row in lookups:
|
for row in lookups:
|
||||||
word = words[row[1]]['word']
|
word = words[row[1]]['word']
|
||||||
category = words[row[1]]['category']
|
category = 'learning' if words[row[1]]['category']==0 else 'mastered'
|
||||||
bookname = bookinfo[row[2]]['bookname']
|
bookname = bookinfo[row[2]]['bookname']
|
||||||
author = bookinfo[row[2]]['author']
|
author = bookinfo[row[2]]['author']
|
||||||
if bookname==info or info == None:
|
if bookname==info or info == None:
|
||||||
# maybe have duplication records
|
# maybe have duplication records
|
||||||
word_list.append((bookname,author,word,category))
|
word_list.append((word,bookname,author,category))
|
||||||
# word tree clicked
|
# word tree clicked
|
||||||
elif tp == 1:
|
elif tp == 1:
|
||||||
pass
|
pass
|
||||||
@@ -732,8 +799,8 @@ if __name__=='__main__':
|
|||||||
searchnote = km.search_clip(books, '巴曙松', 'ALL', 'AUTHOR')
|
searchnote = km.search_clip(books, '巴曙松', 'ALL', 'AUTHOR')
|
||||||
if searchnote[0] > 0: km.export_notes(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_bookname_num(books))
|
||||||
print(km.get_author_num(books))
|
#print(km.get_author_num(books))
|
||||||
|
|
||||||
# add note content to hightlight, then delete note
|
# add note content to hightlight, then delete note
|
||||||
km.add_note_to_highlight(books)
|
km.add_note_to_highlight(books)
|
||||||
|
|||||||
36
kmanapp.py
36
kmanapp.py
@@ -27,18 +27,18 @@ from kman import *
|
|||||||
# import binary resource file(kmanapp_rc.py)
|
# import binary resource file(kmanapp_rc.py)
|
||||||
import kmanapp_rc
|
import kmanapp_rc
|
||||||
|
|
||||||
notes_temp = """<br><span style='font-size:22pt;color:maroon'>《{bookname}》</span>
|
notes_temp = """<br><span style='font-size:18pt;color:maroon'>《{bookname}》</span>
|
||||||
<span style='font-size:22pt;color:maroon'> {author} </span>
|
<span style='font-size:18pt;color:maroon'> {author} </span>
|
||||||
<span style='font-size:22pt;color:maroon'> ({time}) </span>
|
<span style='font-size:18pt;color:maroon'> ({time}) </span>
|
||||||
<span style='font-size:11pt;color:maroon'> 【{note}】 </span><hr><br><br>
|
<span style='font-size:11pt;color:maroon'> 【{note}】 </span><hr><br><br>
|
||||||
<span style='font-size:22pt;color:#31849B'>{content}</span>
|
<span style='font-size:18pt;color:#31849B'>{content}</span>
|
||||||
<span style='font-size:11pt;color:maroon'>【P{position}】</span><br>"""
|
<span style='font-size:11pt;color:maroon'>【P{position}】</span><br>"""
|
||||||
|
|
||||||
words_temp = """<br><span style='font-size:22pt;color:maroon'>{usage}</span><br><br>
|
words_temp = """<br><span style='font-size:18pt;color:#31849B'>{usage}</span><br><br>
|
||||||
<span style='font-size:12pt;color:maroon'> {bookname} </span>
|
<span style='font-size:14pt;color:#2F4F4F'> {bookname} </span>
|
||||||
<span style='font-size:12pt;color:maroon'> {author} </span>
|
<span style='font-size:14pt;color:maroon'> {author} </span>
|
||||||
<span style='font-size:12pt;color:maroon'> {category} </span>
|
<span style='font-size:12pt;color:maroon'> {category} </span>
|
||||||
<span style='font-size:12pt;color:maroon'> {timestamp} </span>
|
<span style='font-size:12pt;color:#696969'> {timestamp} </span>
|
||||||
<span style='font-size:12pt;color:#31849B'>{position}</span><hr><br><br>"""
|
<span style='font-size:12pt;color:#31849B'>{position}</span><hr><br><br>"""
|
||||||
|
|
||||||
ONLY_TEST = 1
|
ONLY_TEST = 1
|
||||||
@@ -172,9 +172,9 @@ class kmanWindow(QMainWindow):
|
|||||||
|
|
||||||
index = self.ui.tableView.currentIndex()
|
index = self.ui.tableView.currentIndex()
|
||||||
if index.row() == -1:
|
if index.row() == -1:
|
||||||
word = self.filter_list[0][2]
|
word = self.filter_list[0][0]
|
||||||
else:
|
else:
|
||||||
word = index.sibling(index.row(), 2).data()
|
word = index.sibling(index.row(), 0).data()
|
||||||
|
|
||||||
txt = ""
|
txt = ""
|
||||||
for row in lookups:
|
for row in lookups:
|
||||||
@@ -196,7 +196,7 @@ class kmanWindow(QMainWindow):
|
|||||||
columns = ['Type','Bookname','Author','Position','Date','Content'])
|
columns = ['Type','Bookname','Author','Position','Date','Content'])
|
||||||
else:
|
else:
|
||||||
pdframe = pd.DataFrame(mlist, \
|
pdframe = pd.DataFrame(mlist, \
|
||||||
columns = ['Bookname','Author','Word','Category'])
|
columns = ['Word','Bookname','Author','Category'])
|
||||||
return pdframe
|
return pdframe
|
||||||
|
|
||||||
def tabledata_update_slot(self, s):
|
def tabledata_update_slot(self, s):
|
||||||
@@ -427,7 +427,6 @@ class kmanWindow(QMainWindow):
|
|||||||
word_bookname_item.setAccessibleDescription('word_bookname')
|
word_bookname_item.setAccessibleDescription('word_bookname')
|
||||||
word_parent_item.appendRow(word_bookname_item)
|
word_parent_item.appendRow(word_bookname_item)
|
||||||
|
|
||||||
print( [numwords, wordnum] )
|
|
||||||
if numwords > 0:
|
if numwords > 0:
|
||||||
for k, v in wordnum.items():
|
for k, v in wordnum.items():
|
||||||
item = QStandardItem('{} ({})'.format(k, v))
|
item = QStandardItem('{} ({})'.format(k, v))
|
||||||
@@ -475,8 +474,18 @@ class kmanWindow(QMainWindow):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def export(self):
|
def export(self):
|
||||||
self.km.export_notes(self.filter_books, 'export', ft='MD')
|
if self.tree_selected.split('_')[0]=='note':
|
||||||
|
self.export_filter_notes()
|
||||||
|
else:
|
||||||
|
self.export_filter_words()
|
||||||
print("call export()")
|
print("call export()")
|
||||||
|
|
||||||
|
def export_filter_notes(self):
|
||||||
|
self.km.export_notes(self.filter_books, 'export', ft='MD')
|
||||||
|
pass
|
||||||
|
|
||||||
|
def export_filter_words(self):
|
||||||
|
self.km.export_words(self.words_data, self.filter_list, 'export', ft='MD')
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def messagebox(self, ico=1, info=''):
|
def messagebox(self, ico=1, info=''):
|
||||||
@@ -541,7 +550,6 @@ class nTableModel(QAbstractTableModel):
|
|||||||
if orientation == Qt.Vertical:
|
if orientation == Qt.Vertical:
|
||||||
return str(self._data.index[section])
|
return str(self._data.index[section])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
|
|||||||
35
x
Normal file
35
x
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
''' move to class kmanWindow kmanapp.py
|
||||||
|
XXX
|
||||||
|
def export_notes(self, bks, fnpref, ft='MD'):
|
||||||
|
"""format output and write to file
|
||||||
|
markdown format:
|
||||||
|
TYPE | bookname | author | marktime | content
|
||||||
|
--|--|--|--|--
|
||||||
|
xx|xx|xx|xx|xx
|
||||||
|
|
||||||
|
CSV format:
|
||||||
|
TYPE,bookname,author,marktime,content
|
||||||
|
xx,xx,xx,xx,xx
|
||||||
|
|
||||||
|
marktime: 20200403 PM 3:0:3 星期五
|
||||||
|
|
||||||
|
Args:
|
||||||
|
bks: books dict
|
||||||
|
f: can be 'MD'/'JSON'/'CSV'
|
||||||
|
|
||||||
|
Returns: special format of 'bks' dict
|
||||||
|
"""
|
||||||
|
|
||||||
|
suff = {'MD':'.md','CSV':'.csv','JSON':'.json'}
|
||||||
|
op = fnpref+suff[ft]
|
||||||
|
|
||||||
|
with open(op, 'w', encoding='utf8', errors='ignore') as fw:
|
||||||
|
if ft=='JSON':
|
||||||
|
fw.write(json.dumps(bks, indent=4, sort_keys=True, ensure_ascii=False))
|
||||||
|
elif ft in ['MD','CSV']:
|
||||||
|
for s in self.format_note_data(bks, ft):
|
||||||
|
fw.write(s)
|
||||||
|
fw.write('\n')
|
||||||
|
else:
|
||||||
|
fw.write(json.dumps(bks)) # only for load back
|
||||||
|
'''
|
||||||
Reference in New Issue
Block a user