From b5c554249dd4ba3cdca00217587189dfeafc0fa6 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Thu, 26 Mar 2020 08:21:52 +0800 Subject: [PATCH 01/28] =?UTF-8?q?=E6=9B=B4=E6=96=B0readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 127 +++++++++--------------------------------- icon.ico | Bin 67646 -> 0 bytes memorytools/README.md | 39 ------------- pic.py | 7 --- pic2py.py | 35 ------------ 5 files changed, 27 insertions(+), 181 deletions(-) delete mode 100644 icon.ico delete mode 100644 memorytools/README.md delete mode 100644 pic.py delete mode 100644 pic2py.py diff --git a/README.md b/README.md index 7807fe2..a3abca5 100644 --- a/README.md +++ b/README.md @@ -1,112 +1,39 @@ -# MemoryTools - python写的小工具合集 +## Memory Tools V1.5.5 -常见错误: +> 2020/3/25 更新 -``` -requests.exceptions.ConnectionError: ('Connection aborted.', TimeoutError(10060, '由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。', None, 10060, None)) -``` +--- -$$ -\frac{du_{i}}{dt})= \sum _{j}T_{ij}v_{i}- \frac{u_{i}}{R_{i}}+I_{i} -$$ +#### 软件功能 -$$ -=- \left[ \frac{1}{3} \frac{0}{1} \frac{1}{1} \right] ,B=- \left[ \frac{1}{1}^{1} \frac{0}{1}, \frac{1}{1} \right] A -$$ +- **复制翻译**:翻译剪切板的文本,并弹框显示结果。 + - **中文-->英文**:中文翻译成英文,如果复制的文本英文的比例过高,则不会翻译。 + - **英文-->中文**:英文翻译成中文,如果复制的文本中文的比例过高,则不会翻译。 + - **英文 <-> 中文**:中英互译,检测复制的文本是哪种语言,然后翻译成另一种语言。 + - **去除换行**:如果是从pdf上复制,则每一行末尾都会加入换行,结果就不准确,开启去除换行可以避免。 + - **严格模式**:默认使用语言自动检测,如果开启严格模式,则将设置源语言。(可以在谷歌翻译上试一下,在中英文混排时可能有一点差异) -$$ - \frac{dE}{dt}= \sum _{i} \frac{ \partial E}{ \partial v_{i}} \frac{dv_{i}}{dt}= \sum _{i}( \sum _{i}T_{ij} \nu _{j}- \frac{u_{i}}{R_{i}}+I_{i}) -$$ +- **OCR识别**:对剪切板中的图片进行OCR识别,并弹框显示。 + - **识别:文本**:识别普通的文本。 + - **识别:公式**:可以识别公式,并转换成 Latex 代码。(准确率emmm...) + - **去除换行**:是否去除识别后文本中的换行。识别公式时,此项不起作用。 -$$ - \frac{dE}{dt}=- \sum _{i} \frac{dv_{i}}{dt}( \sum _{j}T_{ij} \nu _{j}- \frac{u_{i}}{R_{i}}+I_{i} -$$ +- **休息提醒**:在你工作一段时间以后,提醒你该休息了。 + - **更改时间**:提醒时间默认90分钟,可以自己更改。 -$$ -C_i( \frac{du_{t}}{dt})= \sum _{J}T_{j}v_{j}- \frac{u_{1}}{R_{1}}+ -$$ +--- -$$ - \frac{dE}{dt}=- \sum C_{i}( \frac{dv_{i}}{dt})( \frac{du_{i}}{dt}) -$$ +#### 软件说明 -$$ - A=- \left[ \frac{1}{3} \frac{0}{1}- \frac{1}{1} \right] ,B=- \left[ \frac{1}{1} \right] ^{ \frac{1}{2}}- \frac{1}{1} -$$ +1. 复制翻译使用谷歌翻译的接口。 +2. 如果翻译后的结果与未翻译时一样,则不会显示。 +3. OCR使用百度AI开放平台的接口,每天有一定的次数限制。 +4. 当OCR设置为识别公式时,仍然可以识别文本,但是可能会发生意料之外的错误。 +5. 请按时休息 :smile:。 -$$ - \frac{du}{dt}=Au-b -$$ +--- -$$ - C_{1}( \frac{du_{i}}{dt})= \sum _{j}T_{i}v_{j}- \frac{u_{1}}{R_{1}}+I_{1} -$$ - -$$ - ( \frac{du_{i}}{dt})= \sum _{J}T_{ij}v_{j}- \frac{u_{i}}{R_{j}} -$$ - -$$ --ΣI,(t) í=1 j≠i í=1 - E \left[ \nu (t) \right] =- \frac{1}{2} \sum _{i=1}^{n} \sum _{j \neq i}w_{ij}v_{i}(t) \nu _{j}(t) n -$$ - -$$ -i=1 E \left[ \nu (t) \right] =- \frac{1}{2} \sum _{i=1}^{n} \sum _{j \neq i}w_{ij}v_{i}(t)v_{j}(t)- ΣI,,(1) n -$$ - -$$ -E[v(t)]=-\frac{1}{2} \sum_{i=1}^{n} \sum_{j \neq i} w_{i j} v_{i}(t) v_{j}(t)-\sum_{i=1}^{n} I_{i} v_{i}(t) -$$ - -$$ -E(v)=-\frac{1}{2} \sum_{i} \sum_{j} T_{i j} v_{i} v_{j}+\sum_{i} \frac{1}{R_{i}} \int_{0}^{v_{i}} \Psi^{-1}(v) d v-\sum_{i} I_{i} v_{i} -$$ - -$$ - E(v)=- \frac{1}{2} \sum _{i} \sum _{j}T_{ij} \nu _{i} \nu _{j}+ \sum _{i} \frac{1}{R_{i}} \int _{0}^{v_{i}} \varphi ^{-1}(v)dv- \sum _{i}I_{i}v_{i} -$$ - -$$ - E( \nu )=- \frac{1}{2} \sum _{i} \sum _{j}T_{ij}v_{i} \nu _{j}+ \sum _{i} \frac{1}{R_{i}} \int _{i}^{v_{i}} \Phi ^{-1}( \nu )dv- \sum _{i}I_{i}v_{i} -$$ - -$$ - \sum _{i=1}^{n} \sum _{i=1}^{n}(t) =- \frac{1}{2} \sum _{i=1}^{n} \sum _{j \neq i}w_{ij}v_{i}(t) \nu _{j}(t)- \sum _{i=1}^{n} -$$ - -$$ - E \left[ \nu (t) \right] =- \frac{1}{2} \sum _{i=1}^{n} \sum _{j=t}w_{ij} \nu _{i}(t) \nu _{j}(t)- \sum _{i=1}^{n}I_{i}v_{i}(t) -$$ - -$$ - \left[ \nu (t+1) \right] -E \left[ \nu (t) \right] =- \left[ v_{k}(t+1)-v_{k}(t) \right] \left[ \sum _{i=1}u_{ik} \nu _{i}(t)+I_{k} \right] -$$ - -$$ - u_{i}(t+1)= \sum _{i} \nu _{ij} t)+I_, -$$ - -$$ -\frac{dE}{dt}= \frac{1}{2} \sum _{i=1}^{n} \sum _{j=1}^{n} \frac{d}{dt}(w_{ij}v_{i} \nu _{j})= \frac{1}{2} \sum _{i=1}^{n} \sum _{j=1}^{n} \left[ (v_{i} \nu _{j}) \frac{d}{dt}w_{ij}+w_{ij} \frac{d}{dt}(v_{i} \nu _{j}) \right] -$$ - -$$ -c, - \frac{du_{i}}{dt}=- \frac{u_{i}}{R_{i}}+ \sum _{j=1}^{n} \frac{W(u_{j})}{R_{ij}}+I -$$ - -$$ -i - \frac{du_{i}}{dt}=- \frac{u_{i}}{R_{i}}+ \sum _{j=1}^{n} \frac{ \varphi (u_{j})}{R_{ij}}+I_{i} -$$ - -$$ - ( \frac{du_{i}}{dt})= \sum _{j}T_{ij}v_{i}- \frac{u_{i}}{R_{i}}+I_{i} -$$ - -$$ -c_{i}( \frac{du_{t}}{dt})= \sum _{j}T_{v} \nu _{t}- \frac{u_{1}}{R_{t}}+I_{1} -$$ +#### 关于作者 +1. 作者:Memory +2. 邮箱:memory_d@foxmail.com \ No newline at end of file diff --git a/icon.ico b/icon.ico deleted file mode 100644 index 22d60837992da4c33c8190dd56f66fd691486f36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67646 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 TSm~DAPR=)nAQzGAjsO22cq)v} diff --git a/memorytools/README.md b/memorytools/README.md deleted file mode 100644 index a3abca5..0000000 --- a/memorytools/README.md +++ /dev/null @@ -1,39 +0,0 @@ -## Memory Tools V1.5.5 - -> 2020/3/25 更新 - ---- - -#### 软件功能 - -- **复制翻译**:翻译剪切板的文本,并弹框显示结果。 - - **中文-->英文**:中文翻译成英文,如果复制的文本英文的比例过高,则不会翻译。 - - **英文-->中文**:英文翻译成中文,如果复制的文本中文的比例过高,则不会翻译。 - - **英文 <-> 中文**:中英互译,检测复制的文本是哪种语言,然后翻译成另一种语言。 - - **去除换行**:如果是从pdf上复制,则每一行末尾都会加入换行,结果就不准确,开启去除换行可以避免。 - - **严格模式**:默认使用语言自动检测,如果开启严格模式,则将设置源语言。(可以在谷歌翻译上试一下,在中英文混排时可能有一点差异) - -- **OCR识别**:对剪切板中的图片进行OCR识别,并弹框显示。 - - **识别:文本**:识别普通的文本。 - - **识别:公式**:可以识别公式,并转换成 Latex 代码。(准确率emmm...) - - **去除换行**:是否去除识别后文本中的换行。识别公式时,此项不起作用。 - -- **休息提醒**:在你工作一段时间以后,提醒你该休息了。 - - **更改时间**:提醒时间默认90分钟,可以自己更改。 - ---- - -#### 软件说明 - -1. 复制翻译使用谷歌翻译的接口。 -2. 如果翻译后的结果与未翻译时一样,则不会显示。 -3. OCR使用百度AI开放平台的接口,每天有一定的次数限制。 -4. 当OCR设置为识别公式时,仍然可以识别文本,但是可能会发生意料之外的错误。 -5. 请按时休息 :smile:。 - ---- - -#### 关于作者 - -1. 作者:Memory -2. 邮箱:memory_d@foxmail.com \ No newline at end of file diff --git a/pic.py b/pic.py deleted file mode 100644 index 6708279..0000000 --- a/pic.py +++ /dev/null @@ -1,7 +0,0 @@ -TRANS_ICO = "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACWAAAA8gAAAP4AAAD/AAAA8gAAAPIAAAD8AAAA/wAAAPIAAAC3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAB9AAAAjgAAAOwAAAD/AAAAYQAAACoAAAD/AAAA/wAAAEsAAAA2AAAA/wAAAPYAAAAAAAAAAAAAAAcAAACyAAAA/wAAAP8AAAD/AAAA/wAAAL4AAAAAAAAATAAAAE8AAAAAAAAAjAAAAP8AAADyAAAAAAAAAAAAAAB7AAAA/wAAAHsAAABFAAAA3gAAAP8AAAD/AAAACgAAAEQAAABvAAAAAAAAAP8AAAD/AAAA8gAAAAAAAAAAAAAAlwAAAP8AAAAjAAAAAAAAAMcAAAD/AAAA/wAAAHEAAAA9AAAAUwAAAEMAAAD/AAAA/wAAAPIAAACVAAAA6QAAAP8AAAD/AAAA/wAAAPQAAAD9AAAA/wAAAP8AAADyAAAAAAAAAAAAAADPAAAA/wAAAP8AAADyAAAA/wAAAL0AAACMAAAAZQAAAGIAAABqAAAA4AAAAP8AAAD/AAAA/wAAAFwAAAA7AAAA/wAAAP8AAAD/AAAA8wAAAPoAAABAAAAAsQAAAK8AAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD+AAAASQAAADQAAAC8AAAA/wAAAP4AAACwAAAAyQAAAOoAAAD+AAAA1QAAANYAAADQAAAA0QAAANIAAACWAAAA/wAAAFIAAAAAAAAAbwAAAP8AAAD/AAAANAAAAAAAAACDAAAA9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAArAAAAAAAAAP8AAAAdAAAAYwAAAP0AAAAAAAAAZgAAAPkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADtAAAAcAAAANYAAAD/AAAAmwAAALMAAAD/AAAAuQAAAIAAAADmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8wAAAF8AAABzAAAAaAAAAP0AAADgAAAAYQAAAF0AAACBAAAA7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAACLAAAAJwAAACYAAAB1AAAAZwAAACYAAAAtAAAAtwAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3AAAA/wAAAP8AAAD/AAAA7gAAAPMAAAD/AAAA/wAAAP8AAACTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/ABBTfwAbWXwAHJ54EhTRcBIUk/EAExFADA6XAgAZXIMAG1lIAByeWE/Qk9hv01TAD9JTgA/QUwzP1BBAD89Qw==" -ABOUT_ICO = "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMgAAAJEAAADOAAAA7QAAAO0AAADNAAAAkAAAADEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAkQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvAAAAP8AAAD/AAAA+wAAANoAAADZAAAA3AAAANcAAADjAAAA/wAAAP8AAAC5AAAAAAAAAAAAAAAAAAAAlwAAAP8AAAD/AAAA/wAAAMYAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAP8AAAD/AAAA/wAAAJIAAAAAAAAAKwAAAP8AAAD/AAAA/wAAAP8AAADqAAAAkwAAAB4AAAAAAAAARwAAAKMAAAD/AAAA/wAAAP8AAAD/AAAAJwAAAJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABVAAAAAAAAAKQAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAJcAAADaAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAATgAAAAAAAACMAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADXAAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD1AAAA4gAAAEMAAAAAAAAAjAAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8gAAAPUAAAD/AAAA/wAAAP8AAAD/AAAA4gAAABAAAAAAAAAAAAAAAIYAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPIAAADbAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADCAAAARgAAAAQAAACQAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADXAAAAmwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAC8AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAlwAAACwAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAM0AAAAeAAAAMQAAANQAAAD/AAAA/wAAAP8AAAD/AAAA/wAAACgAAAAAAAAAmAAAAP8AAAD/AAAA/wAAAP8AAACAAAAAAAAAAAAAAAB3AAAA/wAAAP8AAAD/AAAA/wAAAJQAAAAAAAAAAAAAAAAAAAC9AAAA/wAAAP8AAAD/AAAA5gAAAEEAAAA+AAAA4gAAAP8AAAD/AAAA/wAAALoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAJMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAAAAJMAAADPAAAA9gAAAPYAAADPAAAAkgAAADIAAAAAAAAAAAAAAAAAAAAA8A9BTeAHbWXAA3J5g+FTRQGAUk8AgExFAYA6XACAZXIBgG1lAYByeQAAQk8BgE1TgYFJTsADQUzgB1BB8A89Qw==" -CHECK_ICO = "AAABAAEAEBIAAAEAIADwBAAAFgAAACgAAAAQAAAAJAAAAAEAIAAAAAAAAAAAAGEPAABhDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsAAAA9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZwAAAH4AAACDAAAAlQAAABsAAABrAAAA7AAAAAwAAABcAAAAkQAAAH8AAACAAAAAggAAAH0AAAB5AAAAIwAAAPIAAAD/AAAA/wAAAOIAAABFAAAA0AAAAP8AAABrAAAAdgAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAFcAAAD/AAAA0gAAADAAAAAAAAAAeQAAAP8AAAD/AAAA8QAAACAAAAAcAAAARAAAAD4AAAAiAAAAjwAAAP8AAABRAAAA/wAAALoAAAAAAAAAHQAAAPkAAAD/AAAA/wAAAP8AAACaAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAD/AAAAUgAAAP8AAACxAAAAAAAAAJ8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAEoAAAAAAAAAAAAAAAAAAABnAAAA/wAAAFIAAADkAAAAGQAAAC8AAAD/AAAA/wAAAP8AAAD9AAAA/wAAAP8AAADNAAAAAQAAAAAAAAAAAAAAZwAAAP8AAABSAAAALQAAAAEAAADfAAAA/wAAAP8AAACyAAAAUwAAAP4AAAD/AAAA/wAAAHMAAAAAAAAAAAAAAGcAAAD/AAAAUgAAAF4AAAAcAAAAywAAAP8AAAD/AAAASAAAAAAAAACnAAAA/wAAAP8AAADwAAAAHAAAAAAAAABnAAAA/wAAAFIAAAD/AAAAiwAAAAAAAAB/AAAAmAAAAAAAAAAAAAAAJQAAAPcAAAD/AAAA/wAAAJ4AAAAAAAAAYQAAAP8AAABRAAAA/wAAAMcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBAAAA/wAAAP8AAAD/AAAAGAAAAFEAAAD/AAAAUAAAAP8AAAC/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAANgAAAD/AAAA/wAAAKwAAAAXAAAA6AAAAGwAAAD/AAAAvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUAAAA/wAAAP8AAAD/AAAAUAAAAAsAAAA2AAAA/wAAALUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAD/AAAA/wAAAOIAAAARAAAAAAAAAPoAAAD/AAAAvwAAAMEAAADEAAAAxAAAAMQAAADGAAAA3AAAAFkAAAAbAAAA9wAAAP8AAAD/AAAAjgAAAAAAAADSAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADgAAAAAAAAAHUAAAD/AAAA/wAAAP8AAABhAAAADQAAABAAAAAQAAAADwAAAA8AAAAPAAAADwAAAA8AAAANAAAAGwAAAAAAAAAGAAAA3gAAAP8AAADzAAAAXwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG8AAACuAAAAEAAAAAD//yAo//82Kd+HaWP//3Nv//8gVv//dWH//1N0//9pb///MS7//0Nv//9vbv//VG///3Nc//9TMf//Q0///1RP//9TPf//XFA=" -CLOCK_ICO = "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAJAQAQCQEAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICEdDg4P/w4OD/8gICEdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgLxQUFc0UFBXNICAgLwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4eHiUaGhtZGBgZehgYGYMYGBl9GBgZfRgYGYMYGBl6GhobWR4eHiUAAAAAAAAAAAAAAAAAAAAAHBwcTBISE98PDxD/DQ0O/w0NDv8MDA3/DQ0O/w0NDv8MDA3/DQ0O/w0NDv8PDxD/EhIT3xwcHEwAAAAAAAAAABQUFa8ICAn/Dg4P/w8PEP8PDxD/Dw8Q/w8PEP8PDxD/Dw8Q/w8PEP8PDxD/Dg4P/wgICf8UFBWvAAAAAAAAAAAhISETERES4gwMDf8PDxD/Dw8Q/w8PEP8PDxD/Dw8Q/w8PEP8PDxD/Dw8Q/wwMDf8RERLiISEhEwAAAAAAAAAAAAAAACAgIBkQEBHmDQ0O/w8PEP8PDxD/Dw8Q/w8PEP8PDxD/Dw8Q/w0NDv8QEBHmICAgGQAAAAAAAAAAAAAAAAAAAAAAAAAAISEhIRAQEfUNDQ7/Dw8Q/w8PEP8PDxD/Dw8Q/w0NDv8QEBH1ISEhIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVFRa1DAwN/w8PEP8PDxD/Dw8Q/w8PEP8MDA3/FRUWtQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAExMUtQ0NDv8PDxD/Dw8Q/w8PEP8PDxD/DQ0O/xMTFLUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMTFLkNDQ7/Dw8Q/w8PEP8PDxD/Dw8Q/w0NDv8TExS5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUFBWsDAwN/w8PEP8PDxD/Dw8Q/w8PEP8MDA3/FBQVrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhobbAsLDP8PDxD/Dw8Q/w8PEP8PDxD/CwsM/xoaG2wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVFRbACgoM/w4OD/8ODg//CgoM/xUVFsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgYGXAPDxD/Dw8Q/xgYGXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhYXsBYWF7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/n9BTf5/bWXwD3J5gAFTRYABUk/AA0xF4Ac6XPAPZXLwD21l8A9yefAPQk/wD01T8A9JTvgfQUz8P1BB/n89Qw==" -OCR_ICO = "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVAAAA6QAAAOgAAABNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaAAAA/wAAAP8AAAD/AAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0AAAAAAAAAAAAAAAAAAABaAAAA/wAAAP8AAABTAAAAqgAAAP8AAAAAAAAAAAAAAAAAAABIAAAAwwAAAP8AAAD/AAAA/wAAALIAAAB4AAAA/wAAAP8AAABCAAAAAQAAAPoAAABrAAAAAAAAAAAAAACbAAAA/wAAAP8AAAC1AAAAkwAAALUAAAD/AAAA/wAAAP8AAAD+AAAAaQAAAP8AAAB6AAAAAAAAAAAAAACeAAAA/wAAAI4AAAAFAAAAAAAAAAAAAAAAAAAABQAAAIcAAAD/AAAA/wAAAP8AAABsAAAAAAAAAAAAAAA7AAAA/wAAAJMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiwAAAP8AAABzAAAAAAAAAAAAAAAAAAAA0wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+AAAAsQAAAAAAAAAAAAAAAAAAAP8AAACzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAswAAAP8AAAAEAAAAAAAAAAAAAAD/AAAAhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIUAAAD/AAAADgAAAAAAAAAAAAAA/wAAALMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyAAAA/wAAAAQAAAAAAAAAAAAAANMAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAANMAAAAAAAAAAAAAAAAAAAA7AAAA/wAAAJMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkwAAAP8AAAA7AAAAAAAAAAAAAAAAAAAAAAAAAJ4AAAD/AAAAjgAAAAUAAAAAAAAAAAAAAAAAAAAFAAAAjgAAAP8AAACeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmwAAAP8AAAD/AAAAtQAAAJMAAAC1AAAA/wAAAP8AAACbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAwwAAAP8AAAD/AAAA/wAAAMMAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//lBTf/wbWX/5HJ58A1TRcABUk+Pg0xFn8c6XD/nZXI/521lP+dyeT/nQk8/501Tn89JTo+PQUzAH1BB8H89Qw==" -PICK_ICO = "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUVFQAJCQkLPT09OF1dXVdvb29vgYGBiJCQkJaRkZGVhYWFhXJycm5hYWFXRkZGOQ4ODgwdHR0AAAAAAFJSUgAvLy8kkZGRq83NzfHg4OD96urq/9zc3P/Nzc3/zs7O/9vb2//r6+v/4uLi/dHR0fKVlZWuNTU1JmBgYAAAAAASlpaWsfDw8P///////v7+//7+/v/p6en/wMDA/8DAwP/o6Oj//v7+//7+/v//////8vLy/5qamrcFBQUWWlpaZNvb2/j//////Pz8//v7+//+/v7//v7+/8PDw//BwcH//v7+//7+/v/7+/v//Pz8///////e3t76YWFha4aGhqb19fX/6Ojo/3R0dP9XV1f/q6ur//n5+f+enp7/mpqa//r6+v+urq7/WFhY/3Fxcf/m5ub/9/f3/4yMjK6MjIyw+fn5/5SUlP8MDAz/MjIy/ykpKf+lpaX///////////+qqqr/KSkp/zMzM/8MDAz/jo6O//r6+v+SkpK4e3t7k/Hx8f90dHT/TU1N/2RkZP9wcHD/VVVV//b29v/4+Pj/WVlZ/25ubv9lZWX/UFBQ/25ubv/z8/P/gYGBmmNjY27n5+f9l5eX/05OTv99fX3/fHx8/2NjY//4+Pj/+vr6/2dnZ/96enr/fn5+/1BQUP+RkZH/6urq/mpqanY5OTk+zc3N7d7e3v8zMzP/KSkp/zIyMv/AwMD////////////ExMT/NDQ0/yoqKv8wMDD/2tra/9LS0vBBQUFFAAAADJmZmbL5+fn/wsLC/3t7e//AwMD//Pz8//z8/P/8/Pz//f39/8PDw/97e3v/v7+///r6+v+fn5+6AAAAEF5eXgAyMjJgtra2/P///////////v7+//z8/P/8/Pz//Pz8//z8/P/+/v7///////////+9vb39OTk5Z3l5eQAAAAAcAAAAvCUlJf+2trb//Pz8///////9/f3//f39//39/f/9/f3///////z8/P+7u7v/Kioq/wAAAMEAAAAgAAAAVwAAAPgAAAD/FhYW/3p6evTS0tLy6Ojo/+3t7f/s7Oz/5+fn/8/Pz/N6enrzFxcX/wAAAP8AAAD6AAAAXwAAADQAAADdAAAA/wAAAOgBAQFhSEhIO3BwcGh3d3d5c3NzeWlpaWlCQkI8AQEBXQAAAOYAAAD/AAAA4AAAADkAAAACAAAARgAAAIsAAABLAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAABIAAAAiwAAAEkAAAAC//8AAMADAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAAAAAAAAAAAAAAAAAB+AAAA==" -EXIT_ICO = "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAC6AAAA8gAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPIAAAC7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAP8AAAD/AAAAHQAAAAwAAAAOAAAADgAAAAwAAAAbAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAADXAAAA1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAMAAAA1wAAAOcAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAD/AAAA/wAAAAAAAAAMAAAA1wAAAP8AAADVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAA/wAAAP8AAAAPAAAA1wAAAP8AAADXAAAAGQAAAAwAAAAOAAAADgAAAA4AAAAPAAAAEQAAAAAAAAAAAAAAEAAAAP8AAAD/AAAA5AAAAP8AAAD/AAAA8AAAAPEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADXAAAAAAAAAAMAAAD/AAAA/wAAAOQAAAD/AAAA/wAAAPAAAADxAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA1wAAAAAAAAADAAAA/wAAAP8AAAAPAAAA1wAAAP8AAADXAAAAGQAAAAwAAAAOAAAADgAAAA4AAAAPAAAAEQAAAAAAAAAAAAAAEAAAAP8AAAD/AAAAAAAAAAwAAADXAAAA/wAAANUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAD/AAAA/wAAAAAAAAAAAAAADAAAANcAAADmAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAADXAAAA1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAA/wAAAP8AAAAdAAAADAAAAA4AAAAOAAAADAAAABsAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAC6AAAA8gAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPIAAAC7/ABBTfwAbWX8/HJ5/PxTRef8Uk/H/ExFh/w6XAAMZXIADG1lh/xyecf8Qk/n/E1T/PxJTvz8QUz8AFBB/AA9Qw==" diff --git a/pic2py.py b/pic2py.py deleted file mode 100644 index b1703f2..0000000 --- a/pic2py.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# @Time : 2018/6/6 18:29 -# @Author : Octan3 -# @Email : Octan3@stu.ouc.edu.cn -# @File : Pic2py.py -# @Software: PyCharm - -import base64 - - -def pic2py(picture_names, py_name): - """ - 将图像文件转换为py文件 - :param picture_name: - :return: - """ - write_data = [] - for picture_name in picture_names: - print(picture_name) - filename = picture_name.replace('.', '_') - open_pic = open("%s" % picture_name, 'rb') - b64str = base64.b64encode(open_pic.read()) - open_pic.close() - # 注意这边b64str一定要加上.decode() - write_data.append('%s = "%s"\n' % (filename, b64str.decode())) - - with open('%s.py' % py_name, 'w+') as f: - for data in write_data: - f.write(data) - - -if __name__ == '__main__': - pics = ["trans.ico", 'about.ico', 'check.ico', 'clock.ico', 'ocr.ico', 'pick.ico', 'exit.ico'] - pic2py(pics, 'pic') - print("ok") From 8f972bf1e2e3b1f459705cd7190fb2b2728d2ced Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Thu, 26 Mar 2020 14:17:34 +0800 Subject: [PATCH 02/28] v1.6.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 对代码进行整理 --- README.md | 15 +- memorytools/alert.py | 27 +-- memorytools/baiduOCR.py | 20 +- memorytools/boxes.py | 59 ++--- memorytools/config.json | 2 +- memorytools/copytrans.py | 24 +- memorytools/memorytools.py | 26 +-- memorytools/ocr.py | 48 +--- memorytools/setting.py | 328 ++++++++++----------------- memorytools/systray/traybar.py | 43 +++- memorytools/systray/win32_adapter.py | 9 +- memorytools/systrayicon.py | 205 ----------------- memorytools/utils.py | 131 ++++++----- memorytools/xueersiOCR.py | 47 ++-- 14 files changed, 357 insertions(+), 627 deletions(-) delete mode 100644 memorytools/systrayicon.py diff --git a/README.md b/README.md index a3abca5..c501815 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -## Memory Tools V1.5.5 +## Memory Tools V1.6.0 -> 2020/3/25 更新 +> 2020/3/26 更新 --- @@ -25,11 +25,12 @@ #### 软件说明 -1. 复制翻译使用谷歌翻译的接口。 -2. 如果翻译后的结果与未翻译时一样,则不会显示。 -3. OCR使用百度AI开放平台的接口,每天有一定的次数限制。 -4. 当OCR设置为识别公式时,仍然可以识别文本,但是可能会发生意料之外的错误。 -5. 请按时休息 :smile:。 +1. 每次退出会保存程序的配置,下次启动时自动载入。 +2. 复制翻译使用谷歌翻译的接口。 +3. 如果翻译后的结果与未翻译时一样,则不会显示。 +4. OCR使用百度AI开放平台的接口,每天有一定的次数限制。 +5. 当OCR设置为识别公式时,仍然可以识别文本,但是可能会发生意料之外的错误。 +6. 请按时休息 :smile:。 --- diff --git a/memorytools/alert.py b/memorytools/alert.py index 7e19e6b..fef0098 100644 --- a/memorytools/alert.py +++ b/memorytools/alert.py @@ -1,7 +1,8 @@ from time import time from boxes import LabelBox -from setting import * -from utils import * +from setting import ALERT_MSG +from utils import isCheckIcon, isPickIcon + class Alert(object): def __init__(self, root, wt=90): @@ -10,13 +11,13 @@ def __init__(self, root, wt=90): self.is_alert = True self.start_time = time() - def setConfig(self, config): + def setConfig(self, config: dict): if 'is_alert' in config: self.is_alert = config['is_alert'] if 'alert_time' in config: self.alert_time = config['alert_time'] - def getConfig(self): + def getConfig(self) -> dict: config = { 'is_alert': self.is_alert, 'alert_time': self.alert_time @@ -24,12 +25,12 @@ def getConfig(self): return config def createMenu(self): - menu_options = ( - ("开启提醒", isCheckIcon(self.is_alert), self.pauseAlert), - ('30分钟', isPickIcon(self.alert_time == 30), self.changeTime30), - ('60分钟', isPickIcon(self.alert_time == 60), self.changeTime60), - ('90分钟', isPickIcon(self.alert_time == 90), self.changeTime90), - ('120分钟', isPickIcon(self.alert_time == 120), self.changeTime120), + menu_options = ( + ("开启提醒", isCheckIcon(self.is_alert), self.pauseAlert, True), + ('30分钟', isPickIcon(self.alert_time == 30), self.changeTime30, False), + ('60分钟', isPickIcon(self.alert_time == 60), self.changeTime60, False), + ('90分钟', isPickIcon(self.alert_time == 90), self.changeTime90, False), + ('120分钟', isPickIcon(self.alert_time == 120), self.changeTime120, False), ) return menu_options @@ -54,7 +55,7 @@ def pauseAlert(self, sysTrayIcon): def changeTime30(self, sysTrayIcon): self.alert_time = 30 self.root.refreshMenu() - + def changeTime60(self, sysTrayIcon): self.alert_time = 60 self.root.refreshMenu() @@ -62,13 +63,13 @@ def changeTime60(self, sysTrayIcon): def changeTime90(self, sysTrayIcon): self.alert_time = 90 self.root.refreshMenu() - + def changeTime120(self, sysTrayIcon): self.alert_time = 120 self.root.refreshMenu() def start(self): - if self.is_alert and self.alert(): # 是否到达预设的提醒时间 + if self.is_alert and self.alert(): alert_message = "你已经连续工作 %d 分钟了!是时候休息一下了!\n%s" % (self.alert_time, ALERT_MSG) LabelBox('危险警报').show(alert_message, '等你想要继续工作了再点我') self.start_time = time() diff --git a/memorytools/baiduOCR.py b/memorytools/baiduOCR.py index 58f67c8..f5a4ea3 100644 --- a/memorytools/baiduOCR.py +++ b/memorytools/baiduOCR.py @@ -1,18 +1,27 @@ from aip import AipOcr from PIL import Image from utils import pil2bytes -from setting import * +from setting import BAIDU_ERROR_CODES + class BaiduOCR(object): - """docstring for BaiduOCR""" - def __init__(self, accounts: dict): + """ + 因为免费调用API的次数以及频率有限,因此利用百度官方提供的API构建 + 一个多账号的OCR识别的类,可以提升程序处理的能力。 + 传入一个账号的列表,可以根据额度自动切换识别的模式。 + + accounts: 百度AI平台的账号列表 + accounts = [{'APP_ID': '...', 'APP_KEY': '...', 'SECRET_KEY': '...'}, {...}, ...] + """ + def __init__(self, accounts: list): self.index = 0 self.ocrs = [] self.mode = 'basicAccurate' for acco in accounts: self.ocrs.append(AipOcr(acco['APP_ID'], acco['APP_KEY'], acco['SECRET_KEY'])) - def ocr(self, image, newline=True): + def ocr(self, image: Image, newline=True) -> str: + '''OCR识别的主函数,传入一个PIL.Image对象,返回识别的文本。''' if self.mode == 'None': return '当天配额已用完,请更换API或明天再试!' @@ -53,6 +62,3 @@ def ocr(self, image, newline=True): res = ''.join(res) return res - - - \ No newline at end of file diff --git a/memorytools/boxes.py b/memorytools/boxes.py index 99a61ed..5279292 100644 --- a/memorytools/boxes.py +++ b/memorytools/boxes.py @@ -2,25 +2,25 @@ @file: boxes.py @author: Memory @date: 2020/3/23 -@description: +@description: 自定义的一些弹出框 ''' import os import pyperclip as p -from setting import * -from PIL import Image, ImageTk +from PIL import ImageTk from tkinter import Tk, END -from tkinter.ttk import Label, Button, Frame, LabelFrame +from tkinter.ttk import Label, Button, Frame from tkinter.scrolledtext import ScrolledText, Text -from utils import getTextLine +from utils import getTextLine, resizeImg + class BaseBox(Tk): - """docstring for BaseBox""" + """弹出框的基类""" def __init__(self, buttons=[], title='Memory Tools'): super(BaseBox, self).__init__() self.setWindow(title) self.setButton(buttons) - def setWindow(self, title): + def setWindow(self, title: str): self.screen_w = self.winfo_screenwidth() self.screen_h = self.winfo_screenheight() self.title(title) @@ -32,7 +32,7 @@ def setWindow(self, title): min_h = self.screen_h // 3 self.minsize(min_w, min_h) - def setButton(self, buttons): + def setButton(self, buttons: list): ''' 定义底部按钮 ''' @@ -63,32 +63,13 @@ def copy(self): p.copy(txt) self.destroy() - def resizeImg(self, img, max_w, max_h): - ''' - 对img进行缩放,使其长宽不超过给定的 max_w 和 max_h - ''' - img_w, img_h = img.size - if img_w < max_w and img_h < max_h: - return img - - if img_w * max_h > img_h * max_w: - new_w = max_w - new_h = img_h * (new_w / img_w) - img = img.resize((int(new_w), int(new_h))) - else: - new_h = max_h - new_w = img_w * (new_h / img_h) - img = img.resize((int(new_w), int(new_h))) - - return img - class TextTextBox(BaseBox): def __init__(self, title='MemoryBox'): buttons = [('复制', self.copy), ] super(TextTextBox, self).__init__(buttons, title) - - def show(self, src, dest): + + def show(self, src: str, dest: str): h1 = min(10, max(5, getTextLine(src)+1)) h2 = min(10, max(5, getTextLine(dest)+1)) @@ -104,12 +85,13 @@ def show(self, src, dest): self.start() + class ImageBox(BaseBox): def __init__(self, title='MemoryBox'): super(ImageBox, self).__init__([], title) def show(self, img): - img = self.resizeImg(img, self.screen_w//3, 100000) + img = resizeImg(img, self.screen_w//3, 100000) w, h = img.size self.geometry('%dx%d' % (w+20, self.screen_h*2//3)) image = ImageTk.PhotoImage(image=img) @@ -119,12 +101,13 @@ def show(self, img): self.cancel_bth.config(text='确定') self.start() + class LabelBox(BaseBox): """docstring for LabelBox""" def __init__(self, title='MemoryBox'): super(LabelBox, self).__init__([], title) - - def show(self, text, button=None): + + def show(self, text: str, button=None): self.minsize(self.screen_w//3, self.screen_h//5) label = Label(self, text=text, font=("微软雅黑", 12)) label.pack(padx=10, pady=50) @@ -132,6 +115,7 @@ def show(self, text, button=None): self.cancel_bth.config(text=button) self.start() + class ImageTextBox(BaseBox): '''用来显示一张图片和一个文本框,会根据图片的大小和比例调整排列的方式''' def __init__(self, title='MemoryBox'): @@ -147,24 +131,24 @@ def setSize(self, img): if img_w > img_h * aspect_ratio: w, h = self.screen_w * 0.9, self.screen_h * 0.35 - img = self.resizeImg(img, w, h) + img = resizeImg(img, w, h) img_w, img_h = img.size width = max(self.screen_w // 3, img_w+20) self.maxsize(width, int(self.screen_h*0.9)) else: w, h = self.screen_w * 0.45, self.screen_h * 0.7 - img = self.resizeImg(img, w, h) + img = resizeImg(img, w, h) img_w, img_h = img.size width = max(self.screen_w // 3, 2 * img_w + 70) self.maxsize(width, int(self.screen_h*0.9)) return img - def show(self, img, txt): + def show(self, img, txt: str): ''' 显示 ''' - img = self.setSize(img) + img = self.setSize(img) w, h = img.size self.tkImage = ImageTk.PhotoImage(image=img) @@ -182,5 +166,6 @@ def show(self, img, txt): self.start() + if __name__ == '__main__': - LabelBox().show("虽然你关掉了休息提醒,但还是要注意身体!", '确认') \ No newline at end of file + LabelBox().show("虽然你关掉了休息提醒,但还是要注意身体!", '确认') diff --git a/memorytools/config.json b/memorytools/config.json index 5d0dac6..e298c54 100644 --- a/memorytools/config.json +++ b/memorytools/config.json @@ -1 +1 @@ -{"alert": {"is_alert": true, "alert_time": 60}, "copytrans": {"is_trans": true, "newline": true, "strict": false, "mode": "both", "src": "en", "dest": "zh-cn"}, "ocr": {"is_ocr": true, "newline": true, "mode": "formula"}} \ No newline at end of file +{"alert": {"is_alert": true, "alert_time": 60}, "copytrans": {"is_trans": true, "newline": false, "strict": false, "mode": "both", "src": "zh-cn", "dest": "en"}, "ocr": {"is_ocr": true, "newline": false, "mode": "formula"}} \ No newline at end of file diff --git a/memorytools/copytrans.py b/memorytools/copytrans.py index cc01564..7f447aa 100644 --- a/memorytools/copytrans.py +++ b/memorytools/copytrans.py @@ -1,7 +1,7 @@ import pyperclip as p from boxes import TextTextBox from googletransx import Translator -from utils import * +from utils import isCheckIcon, isPickIcon, judgeLanguage class CopyTrans(object): @@ -16,7 +16,7 @@ def __init__(self, root): self.last = '' # 记录上次的剪切板内容 self.translator = Translator(service_urls=['translate.google.cn']) # 获得翻译接口 - def setConfig(self, config): + def setConfig(self, config: dict): if 'is_trans' in config: self.is_trans = config['is_trans'] if 'newline' in config: @@ -30,7 +30,7 @@ def setConfig(self, config): if 'dest' in config: self.dest = config['dest'] - def getConfig(self): + def getConfig(self) -> dict: config = { 'is_trans': self.is_trans, 'newline': self.newline, @@ -41,14 +41,14 @@ def getConfig(self): } return config - def createMenu(self): - menu_options = ( - ("开启翻译", isCheckIcon(self.is_trans), self.pauseTrans), - ('去除换行', isCheckIcon(not self.newline), self.turnNewline), - ('严格模式', isCheckIcon(self.strict), self.turnStrict), - ('英文 <-> 中文', isPickIcon(self.mode=='both'), self.bothMode), - ('英文 --> 中文', isPickIcon(self.mode=='en2zh'), self.en2zhMode), - ('中文 --> 英文', isPickIcon(self.mode=='zh2en'), self.zh2enMode), + def createMenu(self) -> tuple: + menu_options = ( + ("开启翻译", isCheckIcon(self.is_trans), self.pauseTrans, True), + ('去除换行', isCheckIcon(not self.newline), self.turnNewline, True), + ('严格模式', isCheckIcon(self.strict), self.turnStrict, True), + ('英文 <-> 中文', isPickIcon(self.mode=='both'), self.bothMode, False), + ('英文 --> 中文', isPickIcon(self.mode=='en2zh'), self.en2zhMode, False), + ('中文 --> 英文', isPickIcon(self.mode=='zh2en'), self.zh2enMode, False), ) return menu_options @@ -79,7 +79,7 @@ def turnNewline(self, sysTrayIcon): self.newline = not self.newline self.root.refreshMenu() - def trans(self, translator, source): + def trans(self, translator: Translator, source: str): if source == "" or source == self.last: # 是否为空或者跟上次一样 return None diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index 72fc2ff..d84b020 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -1,14 +1,12 @@ -import os from PIL import Image from time import sleep from ocr import OCR from alert import Alert from copytrans import CopyTrans -from threading import Thread from systray import SysTrayIcon from boxes import ImageBox -from utils import * -from setting import * +from utils import getSrc, readConfig, writeConfig +from setting import HOVER_TEXT, ABOUT_IMG class MemoryTool(object): @@ -23,23 +21,25 @@ def __init__(self): self.ct.setConfig(config['copytrans']) self.ocr.setConfig(config['ocr']) - self.systray = SysTrayIcon(self.icon, HOVER_TEXT, self.createMenu(), \ - on_quit=self.bye, default_menu_index=1, exit_ico=getSrc('exit.ico')) + self.systray = SysTrayIcon(self.icon, HOVER_TEXT, self.createMenu(), + on_quit=self.bye, default_menu_index=1, + exit_ico=getSrc('exit.ico') + ) self.is_about = False self.end = False - def about(self, sysTrayIcon): + def about(self, sysTrayIcon: SysTrayIcon): '''菜单中的 关于 选项,如果在线程中调用会出错,因此用一个变量控制,在主线程中显示信息''' self.is_about = True - + def createMenu(self): '''创建托盘程序的菜单''' self.menu_options = ( - ('复制翻译', getSrc('trans.ico'), self.ct.createMenu()), - ('OCR识别', getSrc('ocr.ico'), self.ocr.createMenu()), - ('休息提醒', getSrc('alert.ico'), self.alert.createMenu()), - ('关于', getSrc('about.ico'), self.about), + ('复制翻译', getSrc('trans.ico'), self.ct.createMenu(), True), + ('OCR识别', getSrc('ocr.ico'), self.ocr.createMenu(), True), + ('休息提醒', getSrc('alert.ico'), self.alert.createMenu(), True), + ('关于', getSrc('about.ico'), self.about, True), ) return self.menu_options @@ -47,7 +47,7 @@ def refreshMenu(self): '''创新菜单''' self.systray.refreshMenu(self.createMenu()) - def bye(self, sysTrayIcon): + def bye(self, sysTrayIcon: SysTrayIcon): '''退出程序时将配置写到文件中''' self.end = True config = {} diff --git a/memorytools/ocr.py b/memorytools/ocr.py index 7aaf662..29c0b0d 100644 --- a/memorytools/ocr.py +++ b/memorytools/ocr.py @@ -3,8 +3,8 @@ from baiduOCR import BaiduOCR from xueersiOCR import LatexOCR from boxes import ImageTextBox -from setting import * -from utils import * +from setting import BAIDU_ACCOUNTS, XUEERSI_ACCOUNTS +from utils import isCheckIcon, isPickIcon, getRect, Color class OCR(object): @@ -16,7 +16,7 @@ def __init__(self, root): self.textocr = BaiduOCR(BAIDU_ACCOUNTS) self.formulaocr = LatexOCR(XUEERSI_ACCOUNTS) - def setConfig(self, config): + def setConfig(self, config: dict): if 'is_ocr' in config: self.is_ocr = config['is_ocr'] if 'newline' in config: @@ -24,7 +24,7 @@ def setConfig(self, config): if 'mode' in config: self.mode = config['mode'] - def getConfig(self): + def getConfig(self) -> dict: config = { 'is_ocr': self.is_ocr, 'newline': self.newline, @@ -32,12 +32,12 @@ def getConfig(self): } return config - def createMenu(self): - menu_options = ( - ("开启OCR", isCheckIcon(self.is_ocr), self.pauseOcr), - ('去除换行', isCheckIcon(not self.newline), self.turnNewline), - ('识别文本', isPickIcon(self.mode=='text'), self.textMode), - ('识别公式', isPickIcon(self.mode=='formula'), self.formulaMode), + def createMenu(self) -> tuple: + menu_options = ( + ("开启OCR", isCheckIcon(self.is_ocr), self.pauseOcr, True), + ('去除换行', isCheckIcon(not self.newline), self.turnNewline, True), + ('识别文本', isPickIcon(self.mode=='text'), self.textMode, False), + ('识别公式', isPickIcon(self.mode=='formula'), self.formulaMode, False), ) return menu_options @@ -80,34 +80,6 @@ def start(self): p.copy('') ImageTextBox('OCR识别结果').show(im, text) - # def setting(self, sysTrayIcon): - # msg = "需要设置百度AI平台(https://ai.baidu.com/)的API才能进行OCR识别" - # title = "设置百度API" - # fieldNames = ["*APP_ID","*API_KEY","*SECRET_KEY"] - # fieldValues = [] - # fieldValues = g.multenterbox(msg, title, fieldNames) - # while True: - # if fieldValues == None: - # break - # errmsg = "" - # for i in range(len(fieldNames)): - # option = fieldNames[i].strip() - # if fieldValues[i].strip() == "" and option[0] == "*": - # errmsg += ("【%s】为必填项 " %fieldNames[i]) - # if errmsg == "": - # break - # fieldValues = g.multenterbox(errmsg, title, fieldNames, fieldValues) - - # if fieldValues: - # config = read_config() - # ocr = config['ocr'] - # ocr['APP_ID'] = fieldValues[0] - # ocr['APP_KEY'] = fieldValues[1] - # ocr['SECRET_KEY'] = fieldValues[2] - # config['ocr'] = ocr - # write_config(config) - # self.textocr = BaiduOCR([ocr, ]) - if __name__ == '__main__': OCR().start() diff --git a/memorytools/setting.py b/memorytools/setting.py index e2995e2..8bda5e9 100644 --- a/memorytools/setting.py +++ b/memorytools/setting.py @@ -1,23 +1,22 @@ -import string +from string import punctuation from pic import * -ABOUT_MSG = 'memory tools version 1.5.0' - ABOUT_IMG = 'README.png' - +CONFIG = 'config.json' +SRC_PATH = 'src' ICONS = { 'icon.ico': ICON_ICO, 'trans.ico': TRANS_ICO, 'ocr.ico': OCR_ICO, 'alert.ico': ALERT_ICO, 'exit.ico': EXIT_ICO, 'about.ico': ABOUT_ICO, 'check.ico': CHECK_ICO, 'pick.ico': PICK_ICO - } + } HOVER_TEXT = "Memory Tools" - ALERT_MSG = 'tip: 连续在电脑前工作太久容易脱发,得颈椎病,猝死。' -CONFIG = 'config.json' - -SRC_PATH = 'src' +ALPHADIG = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' +COLOR = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 0, 255), (0, 255, 255)] +PUNCTUATION_MAP = dict((ord(char), None) for char in punctuation) +NOTAS = u'[’·°–!"#$%&\'()*+,-./:;<=>?@,。?★、…【】()《》?“”‘’![\\]^_`{|}~]+' DEFAULT_CONFIG = { 'copytrans': @@ -29,8 +28,8 @@ 'src': 'en', 'dest': 'zh-cn' }, - 'ocr' : - { + 'ocr': + { 'is_ocr': True, 'newline': True, 'mode': 'text' @@ -42,11 +41,6 @@ } } -ALPHADIG = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' -COLOR = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 0, 255), (0, 255, 255)] -REMOVE_PUNCTUATION_MAP = dict((ord(char), None) for char in string.punctuation) -NOTAS = u'[’·°–!"#$%&\'()*+,-./:;<=>?@,。?★、…【】()《》?“”‘’![\\]^_`{|}~]+' - # 学而思AI开方平台的账号 XUEERSI_ACCOUNTS = [ { @@ -67,6 +61,7 @@ } ] +# 百度AI开方平台的账号 BAIDU_ACCOUNTS = [ { 'APP_ID': '18054283', @@ -81,203 +76,118 @@ ] # 学而思平台的所有错误码,来源:https://docai.xueersi.com/books/ai%E6%95%99%E8%82%B2%E5%BC%80%E6%94%BE%E5%B9%B3%E5%8F%B0/page/%E8%BF%94%E5%9B%9E%E7%A0%81%E5%88%97%E8%A1%A8 -ERROR_CODES = { - -15000 : {'reason': 'json字符串化发生错误', 'solution': '联系客服linqi@100tal.com,反映此问题'}, - -15001 : {'reason': 'json对象化发生错误', 'solution': '检查发送给API接口的请求Body中,字符串是否符合Json结构'}, - -15002 : {'reason': '内部请求错误', 'solution': '联系客服linqi@100tal.com,反映此问题'}, - -15101 : {'reason': 'OCR服务内部异常', 'solution': '联系客服linqi@100tal.com,反映此问题'}, - 14000 : {'reason': '参数非法', 'solution': '检查请求参数是否缺失,或参数类型有误'}, - 14001 : {'reason': '缺少app_key参数', 'solution': '检查是否缺失"app_key"参数'}, - 14002 : {'reason': '缺少time_stamp参数', 'solution': '检查是否缺失"time_stamp"参数'}, - 14003 : {'reason': '缺少nonce_str参数', 'solution': '检查是否缺失"nonce_str"参数或长度是否满足要求(1-32个字符长度)'}, - 14004 : {'reason': '缺少sign参数', 'solution': '检查是否缺失"sign"参数'}, - 14005 : {'reason': '图像不存在', 'solution': '检查传入图像URL是否有效,或者图像Base64是否完整且规范'}, - 14011 : {'reason': '应用不存在', 'solution': '检查当前请求API的URL拼写是否正确'}, - 14012 : {'reason': '请求签名无效', 'solution': '检查签名是否正确,或尝试重新获取签名'}, - 14013 : {'reason': 'time_stamp参数无效', 'solution': '检查"time_stamp"参数是否有误'}, - 15001 : {'reason': 'qps超过限制', 'solution': '您的每秒并发量超过了最大限制,请降低并发量重试;或者联系客服申请提高每秒并发量限制'}, - 15002 : {'reason': 'qpd超过限制', 'solution': '您的每日调用量超过了最大限制,请隔日再试;或者联系客服申请提高每日调用量限制'}, - 15003 : {'reason': 'qpm超过限制', 'solution': '您的每分钟并发量超过了最大限制,请降低并发量重试;或者联系客服申请提高每秒并发量限制'}, - 15004 : {'reason': 'interval超过限制', 'solution': '接口调用频率超过访问允许间隔。如果是试用账号,请登录后使用自己的账号。如果希望扩容,请联系商务为您免费提高调用频率。'}, - 15010 : {'reason': '图片解析失败,请重试', 'solution': '检查图片URL是否有效,或者图像Base64是否完整 且规范'}, - 15011 : {'reason': '图片有些问题,请重新拍照', 'solution': '检查图片成像是否正常,图片内部是否有有效图案'}, - 15012 : {'reason': '图片太暗啦,请开启照明', 'solution': '检查图片成像是否过暗,尝试开启闪光灯拍照重试'}, - 15013 : {'reason': '图片太模糊啦,请保证拍照清晰', 'solution': '检查图片成像是否模糊,请保证拍照清晰之后重试'}, - 15020 : {'reason': '客户端发包异常', 'solution': '检查网络是否有波动'}, - 15021 : {'reason': 'Sid获取异常', 'solution': '联系客服linqi@100tal.com,反映此问题'}, - 15022 : {'reason': 'Idx获取异常', 'solution': '联系客服linqi@100tal.com,反映此问题'}, - 15023 : {'reason': '图像获取异常', 'solution': '检查图片URL是否有效,或者图像Base64是否完整且规范'}, - 15024 : {'reason': '图像损坏', 'solution': '检查图片成像是否正常,图片内部是否有有效图案'}, - 15025 : {'reason': '图像模糊', 'solution': '检查图片成像是否模糊,请保证传入清晰图片重试'}, - 15026 : {'reason': '其他图像异常', 'solution': '检查图片问题,或联系客服linqi@100tal.com,反映此问题'}, - 15100 : {'reason': '传入图像尺寸过大或过小', 'solution': '不能大于4MB,长边不能超过4096,短边不能小于15'}, - 16010 : {'reason': 'base64音频编码为[]byte失败', 'solution': '检查base64音频内容是否无效'}, - 16011 : {'reason': '构造请求消息结构失败', 'solution': '检查发送参数是否不符合规范'}, - 16012 : {'reason': '解码服务器返回的响应body中,未获取到响应数据', 'solution': '联系客服linqi@100tal.com,反映此问题'}, - 16013 : {'reason': '对解码服务器发送的http请求,请求失败或未响应', 'solution': '联系客服linqi@100tal.com,反映此问题'}, - 16014 : {'reason': 'socket接收失败', 'solution': 'socket接收失败'}, - 16015 : {'reason': '拉学生名单错误', 'solution': '输入学生名单有误,请检查。'}, - 16016 : {'reason': '解码器返回超时,比如端长时间占用连接', 'solution': '解码服务器连接超时,请稍后再试。'}, - 16017 : {'reason': 'Sid提前结束', 'solution': '您的这段语音已完成识别或者测评。'}, - 16018 : {'reason': '解码器目前繁忙', 'solution': '服务器繁忙,请稍后重试。'}, - 16107 : {'reason': '音频格式错误', 'solution': '请检查您的传入音频格式是否是允许的格式'}, - 16108 : {'reason': '评测文本格式错误,如出现了违规字符', 'solution': '请检查您的传入评测文本是否包含违规字符'}, - 16019 : {'reason': '解码器返回数据无有效声音', 'solution': '请检查您的传入音频是否有有效信息。'}, - 16020 : {'reason': 'pcm错误', 'solution': '请检查您的传入音频是否完整且有效'}, - 16100 : {'reason': 'WebSocket建立连接时,请求协议不是WebSocket握手', 'solution': '请检查您的WebSocket连接'}, - 16101 : {'reason': 'WebSocket建立连接时,无法设置WebSocket连接', 'solution': '请检查您的WebSocket连 接'}, - 16102 : {'reason': '可能是您的WebSocket长链接异常中断了,在WebSocket长连接中,服务端无法正常读取消息', 'solution': '请检查您的WebSocket连接'}, - 16103 : {'reason': '您传入的请求json中:common参数部分的idx属性不是字符型数字', 'solution': '请检查 您的请求数据common中idx的数据类型'}, - 16104 : {'reason': '您传入的请求json中:spec参数部分的assessRef评测文本为空', 'solution': '请检查您 的请求数据spec中是否包含assessRef'}, - 16105 : {'reason': '没有sid或者idx,或者在需要assess_ref的业务中没有传', 'solution': '请检查传入参数中是否缺失sid或idx或assess_ref。'}, - 16106 : {'reason': '音频数据为空', 'solution': '请检查您的传入音频是否有有效信息。'}, - 16109 : {'reason': '此sid已经结束', 'solution': '当前sid服务端已经处理结束'}, - 16110 : {'reason': '此sid已经完全结束', 'solution': '当前sid服务端已经处理结束且触发超时,处于待清理状态'}, - 16111 : {'reason': '您传入的请求json中:common参数部分的sid属性长度不符合长度要求(16-64个字符)', 'solution': '请检查您的传入的sid是否符合要求的长度'} +XUEERSI_ERROR_CODES = { + -15000: {'reason': 'json字符串化发生错误', 'solution': '联系客服linqi@100tal.com,反映此问题'}, + -15001: {'reason': 'json对象化发生错误', 'solution': '检查发送给API接口的请求Body中,字符串是否符合Json结构'}, + -15002: {'reason': '内部请求错误', 'solution': '联系客服linqi@100tal.com,反映此问题'}, + -15101: {'reason': 'OCR服务内部异常', 'solution': '联系客服linqi@100tal.com,反映此问题'}, + 14000: {'reason': '参数非法', 'solution': '检查请求参数是否缺失,或参数类型有误'}, + 14001: {'reason': '缺少app_key参数', 'solution': '检查是否缺失"app_key"参数'}, + 14002: {'reason': '缺少time_stamp参数', 'solution': '检查是否缺失"time_stamp"参数'}, + 14003: {'reason': '缺少nonce_str参数', 'solution': '检查是否缺失"nonce_str"参数或长度是否满足要求(1-32个字符长度)'}, + 14004: {'reason': '缺少sign参数', 'solution': '检查是否缺失"sign"参数'}, + 14005: {'reason': '图像不存在', 'solution': '检查传入图像URL是否有效,或者图像Base64是否完整且规范'}, + 14011: {'reason': '应用不存在', 'solution': '检查当前请求API的URL拼写是否正确'}, + 14012: {'reason': '请求签名无效', 'solution': '检查签名是否正确,或尝试重新获取签名'}, + 14013: {'reason': 'time_stamp参数无效', 'solution': '检查"time_stamp"参数是否有误'}, + 15001: {'reason': 'qps超过限制', 'solution': '您的每秒并发量超过了最大限制,请降低并发量重试;或者联系客服申请提高每秒并发量限制'}, + 15002: {'reason': 'qpd超过限制', 'solution': '您的每日调用量超过了最大限制,请隔日再试;或者联系客服申请提高每日调用量限制'}, + 15003: {'reason': 'qpm超过限制', 'solution': '您的每分钟并发量超过了最大限制,请降低并发量重试;或者联系客服申请提高每秒并发量限制'}, + 15004: {'reason': 'interval超过限制', 'solution': '接口调用频率超过访问允许间隔。如果是试用账号,请登录后使用自己的账号。如果希望扩容,请联系商务为您免费提高调用频率。'}, + 15010: {'reason': '图片解析失败,请重试', 'solution': '检查图片URL是否有效,或者图像Base64是否完整 且规范'}, + 15011: {'reason': '图片有些问题,请重新拍照', 'solution': '检查图片成像是否正常,图片内部是否有有效图案'}, + 15012: {'reason': '图片太暗啦,请开启照明', 'solution': '检查图片成像是否过暗,尝试开启闪光灯拍照重试'}, + 15013: {'reason': '图片太模糊啦,请保证拍照清晰', 'solution': '检查图片成像是否模糊,请保证拍照清晰之后重试'}, + 15020: {'reason': '客户端发包异常', 'solution': '检查网络是否有波动'}, + 15021: {'reason': 'Sid获取异常', 'solution': '联系客服linqi@100tal.com,反映此问题'}, + 15022: {'reason': 'Idx获取异常', 'solution': '联系客服linqi@100tal.com,反映此问题'}, + 15023: {'reason': '图像获取异常', 'solution': '检查图片URL是否有效,或者图像Base64是否完整且规范'}, + 15024: {'reason': '图像损坏', 'solution': '检查图片成像是否正常,图片内部是否有有效图案'}, + 15025: {'reason': '图像模糊', 'solution': '检查图片成像是否模糊,请保证传入清晰图片重试'}, + 15026: {'reason': '其他图像异常', 'solution': '检查图片问题,或联系客服linqi@100tal.com,反映此问题'}, + 15100: {'reason': '传入图像尺寸过大或过小', 'solution': '不能大于4MB,长边不能超过4096,短边不能小于15'}, + 16010: {'reason': 'base64音频编码为[]byte失败', 'solution': '检查base64音频内容是否无效'}, + 16011: {'reason': '构造请求消息结构失败', 'solution': '检查发送参数是否不符合规范'}, + 16012: {'reason': '解码服务器返回的响应body中,未获取到响应数据', 'solution': '联系客服linqi@100tal.com,反映此问题'}, + 16013: {'reason': '对解码服务器发送的http请求,请求失败或未响应', 'solution': '联系客服linqi@100tal.com,反映此问题'}, + 16014: {'reason': 'socket接收失败', 'solution': 'socket接收失败'}, + 16015: {'reason': '拉学生名单错误', 'solution': '输入学生名单有误,请检查。'}, + 16016: {'reason': '解码器返回超时,比如端长时间占用连接', 'solution': '解码服务器连接超时,请稍后再试。'}, + 16017: {'reason': 'Sid提前结束', 'solution': '您的这段语音已完成识别或者测评。'}, + 16018: {'reason': '解码器目前繁忙', 'solution': '服务器繁忙,请稍后重试。'}, + 16107: {'reason': '音频格式错误', 'solution': '请检查您的传入音频格式是否是允许的格式'}, + 16108: {'reason': '评测文本格式错误,如出现了违规字符', 'solution': '请检查您的传入评测文本是否包含违规字符'}, + 16019: {'reason': '解码器返回数据无有效声音', 'solution': '请检查您的传入音频是否有有效信息。'}, + 16020: {'reason': 'pcm错误', 'solution': '请检查您的传入音频是否完整且有效'}, + 16100: {'reason': 'WebSocket建立连接时,请求协议不是WebSocket握手', 'solution': '请检查您的WebSocket连接'}, + 16101: {'reason': 'WebSocket建立连接时,无法设置WebSocket连接', 'solution': '请检查您的WebSocket连 接'}, + 16102: {'reason': '可能是您的WebSocket长链接异常中断了,在WebSocket长连接中,服务端无法正常读取消息', 'solution': '请检查您的WebSocket连接'}, + 16103: {'reason': '您传入的请求json中:common参数部分的idx属性不是字符型数字', 'solution': '请检查 您的请求数据common中idx的数据类型'}, + 16104: {'reason': '您传入的请求json中:spec参数部分的assessRef评测文本为空', 'solution': '请检查您 的请求数据spec中是否包含assessRef'}, + 16105: {'reason': '没有sid或者idx,或者在需要assess_ref的业务中没有传', 'solution': '请检查传入参数中是否缺失sid或idx或assess_ref。'}, + 16106: {'reason': '音频数据为空', 'solution': '请检查您的传入音频是否有有效信息。'}, + 16109: {'reason': '此sid已经结束', 'solution': '当前sid服务端已经处理结束'}, + 16110: {'reason': '此sid已经完全结束', 'solution': '当前sid服务端已经处理结束且触发超时,处于待清理状态'}, + 16111: {'reason': '您传入的请求json中:common参数部分的sid属性长度不符合长度要求(16-64个字符)', 'solution': '请检查您的传入的sid是否符合要求的长度'} } - - +# 百度平台的错误码 BAIDU_ERROR_CODES = { - 4 : '集群超限额', - 14 : 'IAM鉴权失败,建议用户参照文档自查生成sign的方式是否正确,或换用控制台中ak sk的方式调用', - 17 : '每天流量超限额', - 18 : 'QPS超限额,请稍后再试', - 19 : '请求总量超限额', - 100 : '无效参数', - 110 : 'Access Token失效', - 111 : 'Access token过期', - 282000 : '服务器内部错误,如果您使用的是高精度接口,报这个错误码的原因可能是您上传的图片中文字过多,识别超时导致的,建议您对图片进行切割后再识别,其他情况请再次请求, 如果持续出现此类错误,请通过QQ群 (631977213)或工单联系技术支持团队。', - 216100 : '请求中包含非法参数,请检查后重新尝试', - 216101 : '缺少必须的参数,请检查参数是否有遗漏', - 216102 : '请求了不支持的服务,请检查调用的url', - 216103 : '请求中某些参数过长,请检查后重新尝试', - 216110 : 'appid不存在,请重新核对信息是否为后台应用列表中的appid', - 216200 : '图片为空,请检查后重新尝试', - 216201 : '上传的图片格式错误,现阶段我们支持的图片格式为:PNG、JPG、JPEG、BMP,请进行转码或更换图片', - 216202 : '上传的图片大小错误,现阶段我们支持的图片大小为:base64编码后小于4M,分辨率不高于4096*4096 ,请重新上传图片', - 216630 : '识别错误,请再次请求,如果持续出现此类错误,请通过QQ群(631977213)或工单联系技术支持团队 。', - 216631 : '识别银行卡错误,出现此问题的原因一般为:您上传的图片非银行卡正面,上传了异形卡的图片或上传的银行卡正品图片不完整', - 216633 : '识别身份证错误,出现此问题的原因一般为:您上传了非身份证图片或您上传的身份证图片不完整', - 216634 : '检测错误,请再次请求,如果持续出现此类错误,请通过QQ群(631977213)或工单联系技术支持团队 。', - 282003 : '请求参数缺失', - 282005 : '处理批量任务时发生部分或全部错误,请根据具体错误码排查', - 282006 : '批量任务处理数量超出限制,请将任务数量减少到10或10以下', - 282110 : 'URL参数不存在,请核对URL后再次提交', - 282111 : 'URL格式非法,请检查url格式是否符合相应接口的入参要求', - 282112 : 'url下载超时,请检查url对应的图床/图片无法下载或链路状况不好,您可以重新尝试一下,如果多次尝试后仍不行,建议更换图片地址', - 282113 : 'URL返回无效参数', - 282114 : 'URL长度超过1024字节或为0', - 282808 : 'request id xxxxx 不存在', - 282809 : '返回结果请求错误(不属于excel或json)', - 282810 : '图像识别错误' + 4: '集群超限额', + 14: 'IAM鉴权失败,建议用户参照文档自查生成sign的方式是否正确,或换用控制台中ak sk的方式调用', + 17: '每天流量超限额', + 18: 'QPS超限额,请稍后再试', + 19: '请求总量超限额', + 100: '无效参数', + 110: 'Access Token失效', + 111: 'Access token过期', + 282000: '服务器内部错误,如果您使用的是高精度接口,报这个错误码的原因可能是您上传的图片中文字过多,识别超时导致的,建议您对图片进行切割后再识别,其他情况请再次请求, 如果持续出现此类错误,请通过QQ群 (631977213)或工单联系技术支持团队。', + 216100: '请求中包含非法参数,请检查后重新尝试', + 216101: '缺少必须的参数,请检查参数是否有遗漏', + 216102: '请求了不支持的服务,请检查调用的url', + 216103: '请求中某些参数过长,请检查后重新尝试', + 216110: 'appid不存在,请重新核对信息是否为后台应用列表中的appid', + 216200: '图片为空,请检查后重新尝试', + 216201: '上传的图片格式错误,现阶段我们支持的图片格式为:PNG、JPG、JPEG、BMP,请进行转码或更换图片', + 216202: '上传的图片大小错误,现阶段我们支持的图片大小为:base64编码后小于4M,分辨率不高于4096*4096 ,请重新上传图片', + 216630: '识别错误,请再次请求,如果持续出现此类错误,请通过QQ群(631977213)或工单联系技术支持团队 。', + 216631: '识别银行卡错误,出现此问题的原因一般为:您上传的图片非银行卡正面,上传了异形卡的图片或上传的银行卡正品图片不完整', + 216633: '识别身份证错误,出现此问题的原因一般为:您上传了非身份证图片或您上传的身份证图片不完整', + 216634: '检测错误,请再次请求,如果持续出现此类错误,请通过QQ群(631977213)或工单联系技术支持团队 。', + 282003: '请求参数缺失', + 282005: '处理批量任务时发生部分或全部错误,请根据具体错误码排查', + 282006: '批量任务处理数量超出限制,请将任务数量减少到10或10以下', + 282110: 'URL参数不存在,请核对URL后再次提交', + 282111: 'URL格式非法,请检查url格式是否符合相应接口的入参要求', + 282112: 'url下载超时,请检查url对应的图床/图片无法下载或链路状况不好,您可以重新尝试一下,如果多次尝试后仍不行,建议更换图片地址', + 282113: 'URL返回无效参数', + 282114: 'URL长度超过1024字节或为0', + 282808: 'request id xxxxx 不存在', + 282809: '返回结果请求错误(不属于excel或json)', + 282810: '图像识别错误' } -LANGUAGE = { '自动检测':'', '中文':'zh-cn','中文繁体':'zh-tw', '英语':'en', '德语':'de', '俄语':'ru' ,'法语':'fr', - '阿尔巴尼亚语':'sq','阿拉伯语':'ar', '阿姆哈拉语':'am', '阿塞拜疆语':'az', '爱尔兰语':'ga', - '爱沙尼亚语':'et' ,'巴斯克语':'eu' ,'白俄罗斯语':'be', - '保加利亚语':'bg', '冰岛语':'is', '波兰语':'pl', '波斯尼亚语':'bs', - '波斯语':'fa', '布尔语':'af', '丹麦语':'da', - '菲律宾语':'tl', '芬兰语':'fi', '弗里西语':'fy' ,'高棉语':'km', '格鲁吉亚语':'ka', - '古吉拉特语':'gu', '哈萨克语':'kk', '海地克里奥尔语':'ht', - '豪萨语':'ha', '荷兰语':'nl' ,'吉尔吉斯语':'ky', '加利西亚语':'gl', '加泰罗尼亚语':'ca', - '捷克语':'cs', '卡纳达语':'kn', '科西嘉语':'co', '克罗地亚语':'hr', - '库尔德语':'ku', '拉丁语':'la', '拉脱维亚语':'lv', '老挝语':'lo', '立陶宛语':'lt', - '卢森堡语':'lb', '罗马尼亚语':'ro', '马尔加什语':'mg', '马耳他语':'mt', - '马拉地语':'mr', '马拉雅拉姆语':'mf', '马来语':'ms', '马其顿语':'mk', - '毛利语':'mi', '蒙古语':'mn','孟加拉语':'bn', '缅甸语':'my', '苗语':'hmn', '南非克萨语':'xh', '南非祖鲁语':'zu', - '尼泊尔语':'ne', '挪威语':'no', '旁遮普语' :'pa','葡萄牙语':'pt' ,'普什图语':'ps', - '齐切瓦语':'ny', '日语':'ja', '瑞典语':'sv', '萨摩亚语' :'sm','塞尔维亚语':'sr', - '赛所托语':'st','僧伽罗语':'si', '世界语':'eo', '斯洛伐克语':'sk', '斯洛文尼亚语':'sl', - '斯瓦希里语':'sw', '苏格兰盖尔语':'gd', '宿务语':'ceb', '索马里语':'so', '塔吉克语':'tg', '泰卢固语':'te', - '泰米尔语':'ta', '泰语':'th', '土耳其语':'tr', '威尔士语':'cy', '乌尔都语':'ur', - '乌克兰语':'uk', '乌兹别克语':'uz', '西班牙语':'es', '希伯来语':'rw', '希腊语':'el', - '夏威夷语':'haw', '信德语':'sd', '匈牙利语':'hu', '修纳语':'sn', - '亚美尼亚语':'hy', '伊博语':'ig', '意大利语':'it', '意第绪语':'yi', '印地语':'hi', - '印尼巽他':'su', '印尼语':'id', '印尼爪哇语':'jw', '约鲁巴语':'yo', '越南语':'vi' +LANGUAGE = {'自动检测':'', '中文':'zh-cn','中文繁体':'zh-tw', '英语':'en', '德语':'de', '俄语':'ru' ,'法语':'fr', + '阿尔巴尼亚语':'sq','阿拉伯语':'ar', '阿姆哈拉语':'am', '阿塞拜疆语':'az', '爱尔兰语':'ga', + '爱沙尼亚语':'et' ,'巴斯克语':'eu' ,'白俄罗斯语':'be', + '保加利亚语':'bg', '冰岛语':'is', '波兰语':'pl', '波斯尼亚语':'bs', + '波斯语':'fa', '布尔语':'af', '丹麦语':'da', + '菲律宾语':'tl', '芬兰语':'fi', '弗里西语':'fy' ,'高棉语':'km', '格鲁吉亚语':'ka', + '古吉拉特语':'gu', '哈萨克语':'kk', '海地克里奥尔语':'ht', + '豪萨语':'ha', '荷兰语':'nl' ,'吉尔吉斯语':'ky', '加利西亚语':'gl', '加泰罗尼亚语':'ca', + '捷克语':'cs', '卡纳达语':'kn', '科西嘉语':'co', '克罗地亚语':'hr', + '库尔德语':'ku', '拉丁语':'la', '拉脱维亚语':'lv', '老挝语':'lo', '立陶宛语':'lt', + '卢森堡语':'lb', '罗马尼亚语':'ro', '马尔加什语':'mg', '马耳他语':'mt', + '马拉地语':'mr', '马拉雅拉姆语':'mf', '马来语':'ms', '马其顿语':'mk', + '毛利语':'mi', '蒙古语':'mn','孟加拉语':'bn', '缅甸语':'my', '苗语':'hmn', '南非克萨语':'xh', '南非祖鲁语':'zu', + '尼泊尔语':'ne', '挪威语':'no', '旁遮普语' :'pa','葡萄牙语':'pt' ,'普什图语':'ps', + '齐切瓦语':'ny', '日语':'ja', '瑞典语':'sv', '萨摩亚语' :'sm','塞尔维亚语':'sr', + '赛所托语':'st','僧伽罗语':'si', '世界语':'eo', '斯洛伐克语':'sk', '斯洛文尼亚语':'sl', + '斯瓦希里语':'sw', '苏格兰盖尔语':'gd', '宿务语':'ceb', '索马里语':'so', '塔吉克语':'tg', '泰卢固语':'te', + '泰米尔语':'ta', '泰语':'th', '土耳其语':'tr', '威尔士语':'cy', '乌尔都语':'ur', + '乌克兰语':'uk', '乌兹别克语':'uz', '西班牙语':'es', '希伯来语':'rw', '希腊语':'el', + '夏威夷语':'haw', '信德语':'sd', '匈牙利语':'hu', '修纳语':'sn', + '亚美尼亚语':'hy', '伊博语':'ig', '意大利语':'it', '意第绪语':'yi', '印地语':'hi', + '印尼巽他':'su', '印尼语':'id', '印尼爪哇语':'jw', '约鲁巴语':'yo', '越南语':'vi' } - -a = { - 'code': 0, - 'msg': '请求成功', - 'data': - {'recognition': - { - 'ocrId': None, - 'ocrLinesList': - [ - { - 'data': - [ - { - 'alp': None, 'height': 15, 'type': 'word', 'value': 'n', 'width': 6, 'x': 463, 'y': 5 - }, - { - 'alp': None, 'height': 15, 'type': 'word', 'value': ' ', 'width': 6, 'x': 469, 'y': 5 - } - ], - 'type': 'p' - }, - { - 'data': - [ - { - 'alp': None, 'height': 59, 'type': 'word', 'value': ' E \\left[ \\nu (t) \\right] =- \\frac{1}{2} \\sum _{i=1}^{n} \\sum _{j \\neq i}w_{ij}v_{i}(t)v_{j}(t)- ', 'width': 432, 'x': 6, 'y': 5 - }, - { - 'alp': None, 'height': 35, 'type': 'word', 'value': 'Σ', 'width': 68, 'x': 438, 'y': 16 - }, - { - 'alp': None, 'height': 35, 'type': 'word', 'value': 'I', 'width': 68, 'x': 506, 'y': 16 - }, - { - 'alp': None, 'height': 35, 'type': 'word', 'value': ',', 'width': 68, 'x': 575, 'y': 16 - }, - { - 'alp': None, 'height': 35, 'type': 'word', 'value': ',', 'width': 68, 'x': 643, 'y': 16 - }, - { - 'alp': None, 'height': 35, 'type': 'word', 'value': '(', 'width': 68, 'x': 712, 'y': 16 - }, - { - 'alp': None, 'height': 35, 'type': 'word', 'value': '1', 'width': 68, 'x': 781, 'y': 16 - }, - { - 'alp': None, 'height': 35, 'type': 'word', 'value': ') ', 'width': 68, 'x': 849, 'y': 16 - } - ], - 'type': 'p' - }, - { - 'data': - [ - { - 'alp': None, 'height': 18, 'type': 'word', 'value': 'i', 'width': 6, 'x': 452, 'y': 49 - }, - { - 'alp': None, 'height': 18, 'type': 'word', 'value': '=', 'width': 6, 'x': 458, 'y': 49 - }, - { - 'alp': None, 'height': 18, 'type': 'word', 'value': '1 ', 'width': 6, 'x': 464, 'y': 49 - } - ], - 'type': 'p' - } - ], - 'textLinePosition': - [ - [446, 5, 479, 21], - [6, 5, 555, 64], - [452, 49, 470, 67] - ] - }, - 'content': - [ - 'n ', - ' E \\left[ \\nu (t) \\right] =- \\frac{1}{2} \\sum _{i=1}^{n} \\sum _{j \\neq i}w_{ij}v_{i}(t)v_{j}(t)- ΣI,,(1) ', - 'i=1 ' - ], - 'loc': None - } - } \ No newline at end of file diff --git a/memorytools/systray/traybar.py b/memorytools/systray/traybar.py index da1219d..8d29984 100644 --- a/memorytools/systray/traybar.py +++ b/memorytools/systray/traybar.py @@ -2,15 +2,24 @@ from .win32_adapter import * import threading import uuid +# from win32con import MIIM_TYPE +# print(MIIM_TYPE) + class SysTrayIcon(object): """ - menu_options: tuple of tuples (menu text, menu icon path or None, function name) - - menu text and tray hover text should be Unicode - hover_text length is limited to 128; longer text will be truncated - - Can be used as context manager to enable automatic termination of tray - if parent thread is closed: + icon: 托盘图标的路径,unicode编码,最长128 + hover_text: 鼠标悬浮在托盘图标上时的显示的文本 + menu_options: (text, icon, function, separator) + text: 菜单项的文本,unicode编码,最长128 + icon: 菜单项的图标 + fuction: 按下该项调用的函数,或者此项可以换成同样的元组以创造二级菜单 + separator: 菜单项下面是否加一条分隔线 + on_quit: 按下"退出"菜单项时调用的函数 + default_menu_index: + window_class_name: + exit_ico: "退出"菜单项的图标 + + 可以用作上下文管理器,以在关闭父线程时启用托盘的自动终止: with SysTrayIcon(icon, hover_text) as systray: for item in ['item1', 'item2', 'item3']: @@ -30,7 +39,8 @@ def __init__(self, on_quit=None, default_menu_index=None, window_class_name=None, - exit_ico=None): + exit_ico=None + ): self._icon = icon self._icon_shared = False @@ -66,7 +76,8 @@ def __init__(self, self._register_class() def refreshMenu(self, menu_options): - menu_options = menu_options + (('退出', self.exit_ico, self.QUIT),) + '''留了一个外部刷新菜单的函数,可以动态改变菜单''' + menu_options = menu_options + (('退出', self.exit_ico, self.QUIT, False),) self._next_action_id = self.FIRST_ID self._menu_actions_by_id = set() self._menu_options = self._add_ids_to_menu_options(list(menu_options)) @@ -144,7 +155,7 @@ def update(self, icon=None, hover_text=None): def _add_ids_to_menu_options(self, menu_options): result = [] for menu_option in menu_options: - option_text, option_icon, option_action = menu_option + option_text, option_icon, option_action, option_separator = menu_option if callable(option_action) or option_action in SysTrayIcon.SPECIAL_ACTIONS: self._menu_actions_by_id.add((self._next_action_id, option_action)) result.append(menu_option + (self._next_action_id,)) @@ -152,6 +163,7 @@ def _add_ids_to_menu_options(self, menu_options): result.append((option_text, option_icon, self._add_ids_to_menu_options(option_action), + option_separator, self._next_action_id)) else: raise Exception('Unknown item', option_text, option_icon, option_action) @@ -242,15 +254,17 @@ def _show_menu(self): PostMessage(self._hwnd, WM_NULL, 0, 0) def _create_menu(self, menu, menu_options): - for option_text, option_icon, option_action, option_id in menu_options[::-1]: + for option_text, option_icon, option_action, option_separator, option_id in menu_options[::-1]: + if option_separator: + self._insert_separator(menu) if option_icon: option_icon = self._prep_menu_icon(option_icon) - if option_id in self._menu_actions_by_id: item = PackMENUITEMINFO(text=option_text, hbmpItem=option_icon, wID=option_id) InsertMenuItem(menu, 0, 1, ctypes.byref(item)) + # self._insert_separator(menu) else: submenu = CreatePopupMenu() self._create_menu(submenu, option_action) @@ -259,6 +273,11 @@ def _create_menu(self, menu, menu_options): hSubMenu=submenu) InsertMenuItem(menu, 0, 1, ctypes.byref(item)) + def _insert_separator(sekf, menu): + '''插入一条分隔线''' + item = PackMENUITEMINFO(fType=MF_SEPARATOR) + InsertMenuItem(menu, 0, 1, ctypes.byref(item)) + def _prep_menu_icon(self, icon): icon = encode_for_locale(icon) # First load the icon. diff --git a/memorytools/systray/win32_adapter.py b/memorytools/systray/win32_adapter.py index 758dbce..d4cb048 100644 --- a/memorytools/systray/win32_adapter.py +++ b/memorytools/systray/win32_adapter.py @@ -22,7 +22,6 @@ CreatePopupMenu = ctypes.windll.user32.CreatePopupMenu CreateCompatibleDC = ctypes.windll.gdi32.CreateCompatibleDC GetDC = ctypes.windll.user32.GetDC -SetBkMode = ctypes.windll.gdi32.SetBkMode CreateCompatibleBitmap = ctypes.windll.gdi32.CreateCompatibleBitmap GetSysColorBrush = ctypes.windll.user32.GetSysColorBrush FillRect = ctypes.windll.user32.FillRect @@ -47,6 +46,7 @@ MIIM_SUBMENU = 4 MIIM_STRING = 64 MIIM_BITMAP = 128 +MIIM_TYPE = 16 WM_DESTROY = 2 WM_CLOSE = 16 WM_COMMAND = 273 @@ -71,6 +71,7 @@ SM_CYSMICON = 50 COLOR_MENU = 4 DI_NORMAL = 3 +MF_SEPARATOR = 2048 WPARAM = ctypes.wintypes.WPARAM LPARAM = ctypes.wintypes.LPARAM @@ -146,7 +147,7 @@ class NOTIFYICONDATA(ctypes.Structure): _fields_.append(("hBalloonIcon", HANDLE)) -def PackMENUITEMINFO(text=None, hbmpItem=None, wID=None, hSubMenu=None): +def PackMENUITEMINFO(text=None, hbmpItem=None, wID=None, hSubMenu=None, fType=None): res = MENUITEMINFO() res.cbSize = ctypes.sizeof(res) res.fMask = 0 @@ -163,6 +164,10 @@ def PackMENUITEMINFO(text=None, hbmpItem=None, wID=None, hSubMenu=None): if hSubMenu is not None: res.fMask |= MIIM_SUBMENU res.hSubMenu = hSubMenu + if fType is not None: + res.fMask |= MIIM_TYPE + res.fType = fType + return res def LOWORD(w): diff --git a/memorytools/systrayicon.py b/memorytools/systrayicon.py deleted file mode 100644 index 85eb7a3..0000000 --- a/memorytools/systrayicon.py +++ /dev/null @@ -1,205 +0,0 @@ -#!python3 -# -*- coding:utf-8 -*- - -import os -import win32gui -import win32api -import win32con -import win32gui_struct -from utils import * - -class SysTrayIcon(object): - '''TODO''' - QUIT = 'QUIT' - SPECIAL_ACTIONS = [QUIT] - - FIRST_ID = 1023 - - def __init__(self, - icon, - hover_text, - menu_options, - on_quit=None, - default_menu_index=None, - window_class_name=None,): - - self.icon = icon - self.hover_text = hover_text - self.on_quit = on_quit - self.refreshMenu(menu_options) - - self.default_menu_index = (default_menu_index or 0) - self.window_class_name = window_class_name or "SysTrayIconPy" - - message_map = {win32gui.RegisterWindowMessage("TaskbarCreated"): self.restart, - win32con.WM_DESTROY: self.destroy, - win32con.WM_COMMAND: self.command, - win32con.WM_USER+20: self.notify,} - # Register the Window class. - window_class = win32gui.WNDCLASS() - hinst = window_class.hInstance = win32gui.GetModuleHandle(None) - window_class.lpszClassName = self.window_class_name - window_class.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW; - window_class.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW) - window_class.hbrBackground = win32con.COLOR_WINDOW - window_class.lpfnWndProc = message_map # could also specify a wndproc. - classAtom = win32gui.RegisterClass(window_class) - # Create the Window. - style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU - self.hwnd = win32gui.CreateWindow(classAtom, - self.window_class_name, - style, - 0, - 0, - win32con.CW_USEDEFAULT, - win32con.CW_USEDEFAULT, - 0, - 0, - hinst, - None) - win32gui.UpdateWindow(self.hwnd) - self.notify_id = None - self.refreshIcon() - - win32gui.PumpMessages() - - def _addIdsToMenuOptions(self, menu_options): - result = [] - for menu_option in menu_options: - option_text, option_icon, option_action = menu_option - if callable(option_action) or option_action in self.SPECIAL_ACTIONS: - self.menu_actions_by_id.add((self._next_action_id, option_action)) - result.append(menu_option + (self._next_action_id,)) - elif nonStringIterable(option_action): - result.append((option_text, - option_icon, - self._addIdsToMenuOptions(option_action), - self._next_action_id)) - else: - print('Unknown item', option_text, option_icon, option_action) - self._next_action_id += 1 - return result - - def refreshMenu(self, menu_options): - menu_options = menu_options + (('退出', None, self.QUIT),) - self._next_action_id = self.FIRST_ID - self.menu_actions_by_id = set() - self.menu_options = self._addIdsToMenuOptions(list(menu_options)) - self.menu_actions_by_id = dict(self.menu_actions_by_id) - del self._next_action_id - - def refreshIcon(self): - # Try and find a custom icon - hinst = win32gui.GetModuleHandle(None) - if os.path.isfile(self.icon): - icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE - hicon = win32gui.LoadImage(hinst, - self.icon, - win32con.IMAGE_ICON, - 0, - 0, - icon_flags) - else: - print("Can't find icon file - using default.") - hicon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION) - - if self.notify_id: message = win32gui.NIM_MODIFY - else: message = win32gui.NIM_ADD - self.notify_id = (self.hwnd, - 0, - win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP, - win32con.WM_USER+20, - hicon, - self.hover_text) - win32gui.Shell_NotifyIcon(message, self.notify_id) - - def restart(self, hwnd, msg, wparam, lparam): - self.refreshIcon() - - def destroy(self, hwnd, msg, wparam, lparam): - if self.on_quit: self.on_quit(self) - nid = (self.hwnd, 0) - win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid) - win32gui.PostQuitMessage(0) # Terminate the app. - - def notify(self, hwnd, msg, wparam, lparam): - if lparam==win32con.WM_LBUTTONDBLCLK: - # self.executeMenuOption(self.default_menu_index + self.FIRST_ID) - pass - elif lparam==win32con.WM_RBUTTONUP: - self.showMenu() - elif lparam==win32con.WM_LBUTTONUP: - self.showMenu() - return True - - def showMenu(self): - menu = win32gui.CreatePopupMenu() - self.createMenu(menu, self.menu_options) - #win32gui.SetMenuDefaultItem(menu, 1000, 0) - - pos = win32gui.GetCursorPos() - # See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/menus_0hdi.asp - win32gui.SetForegroundWindow(self.hwnd) - win32gui.TrackPopupMenu(menu, - win32con.TPM_LEFTALIGN, - pos[0], - pos[1], - 0, - self.hwnd, - None) - win32gui.PostMessage(self.hwnd, win32con.WM_NULL, 0, 0) - - def createMenu(self, menu, menu_options): - for option_text, option_icon, option_action, option_id in menu_options[::-1]: - if option_icon: - option_icon = self.prepMenuIcon(option_icon) - print(option_icon) - - if option_id in self.menu_actions_by_id: - item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text, - hbmpItem=option_icon, - wID=option_id) - win32gui.InsertMenuItem(menu, 0, 1, item) - else: - submenu = win32gui.CreatePopupMenu() - self.createMenu(submenu, option_action) - item, extras = win32gui_struct.PackMENUITEMINFO(text=option_text, - hbmpItem=option_icon, - hSubMenu=submenu) - win32gui.InsertMenuItem(menu, 0, 1, item) - - def prepMenuIcon(self, icon): - # First load the icon. - ico_x = win32api.GetSystemMetrics(win32con.SM_CXSMICON) - ico_y = win32api.GetSystemMetrics(win32con.SM_CYSMICON) - # hicon = win32gui.LoadImage(0, icon, win32con.IMAGE_ICON, ico_x, ico_y, win32con.LR_LOADFROMFILE) - hicon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION) - print(hicon) - - hdcBitmap = win32gui.CreateCompatibleDC(0) - hdcScreen = win32gui.GetDC(0) - hbm = win32gui.CreateCompatibleBitmap(hdcScreen, ico_x, ico_y) - hbmOld = win32gui.SelectObject(hdcBitmap, hbm) - # Fill the background. - brush = win32gui.GetSysColorBrush(win32con.COLOR_MENU) - win32gui.FillRect(hdcBitmap, (0, 0, 16, 16), brush) - # unclear if brush needs to be feed. Best clue I can find is: - # "GetSysColorBrush returns a cached brush instead of allocating a new - # one." - implies no DeleteObject - # draw the icon - win32gui.DrawIconEx(hdcBitmap, 0, 0, hicon, ico_x, ico_y, 0, 0, win32con.DI_NORMAL) - win32gui.SelectObject(hdcBitmap, hbmOld) - win32gui.DeleteDC(hdcBitmap) - - return hbm - - def command(self, hwnd, msg, wparam, lparam): - id = win32gui.LOWORD(wparam) - self.executeMenuOption(id) - - def executeMenuOption(self, id): - menu_action = self.menu_actions_by_id[id] - if menu_action == self.QUIT: - win32gui.DestroyWindow(self.hwnd) - else: - menu_action(self) diff --git a/memorytools/utils.py b/memorytools/utils.py index ea48499..45d9239 100644 --- a/memorytools/utils.py +++ b/memorytools/utils.py @@ -1,42 +1,69 @@ import os import re -import json -from base64 import b64decode +from json import dumps, loads +from base64 import b64decode, b64encode +from urllib.parse import quote from io import BytesIO -from setting import * +from setting import COLOR, SRC_PATH, ICONS, CONFIG, DEFAULT_CONFIG, NOTAS, PUNCTUATION_MAP + class Color(object): def __init__(self): self.colors = COLOR self.index = 0 - + def next(self): color = self.colors[self.index] self.index = (self.index + 1) % (len(self.colors)) return color -def nonStringIterable(obj): - try: - iter(obj) - except TypeError: - return False - else: - return not isinstance(obj, str) -def getTextLine(text): +def getTextLine(text: str): '''返回所给的文本有几行''' return len(text.split('\n')) -def getRect(x1, y1, x2, y2): + +def getRect(x1: int, y1: int, x2: int, y2: int): '''给定矩形框的左上角和右下角坐标,返回四个角的坐标''' return [(x1, y1), (x2, y1), (x2, y2), (x1, y2)] + +def pil2bytes(im, img_type='png', b64=False): + '''将PIL.Image格式的图像转化为二进制数据''' + bf = BytesIO() + im.save(bf, img_type) + img = bf.getvalue() + + return img + + def bs64toImg(pic_code, pic_name): '''将bs64编码的数据写到文件中''' with open(pic_name, 'wb') as image: image.write(b64decode(pic_code)) -def getSrc(pic): + +def resizeImg(img, max_w: int, max_h: int): + ''' + 对img进行缩放,使其长宽不超过给定的 max_w 和 max_h + ''' + img_w, img_h = img.size + if img_w < max_w and img_h < max_h: + return img + + if img_w * max_h > img_h * max_w: + new_w = max_w + new_h = img_h * (new_w / img_w) + img = img.resize((int(new_w), int(new_h))) + else: + new_h = max_h + new_w = img_w * (new_h / img_h) + img = img.resize((int(new_w), int(new_h))) + + return img + + +def getSrc(pic: str): '''返回对应资源的完整路径''' path = os.path.join(SRC_PATH, pic) file = os.path.abspath(path) @@ -49,22 +76,26 @@ def getSrc(pic): return file -def isCheckIcon(check): + +def isCheckIcon(check: bool): '''是否选中(两种状态)''' return getSrc('check.ico') if check else None -def isPickIcon(pick): + +def isPickIcon(pick: bool): '''是否被选中(多项中的一个)''' return getSrc('pick.ico') if pick else None -def img2base64(image): + +def img2base64(image: str): '''将图像从文件中读取出来并转化为base64编码''' with open(image, 'rb') as bin_data: image_data = bin_data.read() - image_data_base64 = base64.b64encode(image_data) + image_data_base64 = b64encode(image_data) image_data_base64 = quote(image_data_base64) return image_data_base64 + def readConfig(name=CONFIG): '''读配置文件''' if name == CONFIG and not os.path.exists(name): @@ -72,41 +103,45 @@ def readConfig(name=CONFIG): try: with open(name, "r") as f: data = f.read() - return json.loads(data) + return loads(data) except Exception as e: print(e) return DEFAULT_CONFIG -def writeConfig(data, name=CONFIG): + +def writeConfig(data: dict, name=CONFIG): '''写配置文件''' try: - data = json.dumps(data) + data = dumps(data) with open(name, "w") as f: f.write(data) except Exception as e: print(e) + def resetConfig(name=CONFIG): '''重置配置文件''' writeConfig(DEFAULT_CONFIG, name) -def filterStr(sentence): + +def filterStr(sentence: str): '''过滤掉字符串中的标点符号''' sentence = re.sub(NOTAS, '', sentence) - sentence = sentence.translate(REMOVE_PUNCTUATION_MAP) + sentence = sentence.translate(PUNCTUATION_MAP) sentence = re.sub('[0-9]', '', sentence).strip() sentence = re.sub(' ', '', sentence).strip() return sentence -def judgeLanguage(s): + +def judgeLanguage(sentence: str): '''判断一句话里面英文和中文的占比''' - s = filterStr(s) + sentence = filterStr(sentence) en_pattern = re.compile(u"[a-zA-Z]") zh_pattern = re.compile(u"[\u4e00-\u9fa5]") - en = re.findall(en_pattern, s) - zh = re.findall(zh_pattern, s) + en = re.findall(en_pattern, sentence) + zh = re.findall(zh_pattern, sentence) en_num = len(en) // 3 zh_num = len(zh) total = en_num + zh_num @@ -114,34 +149,24 @@ def judgeLanguage(s): return ('en', en_num / total) else: return ('zh-cn', zh_num / total) - # return (en_num / total, zh_num / total) - - # print(len(s)) - # re_words = re.compile(u"[a-zA-Z]") - # res = re.findall(re_words, s) # 查询出所有的匹配字符串 - # print(res) - # res2 = re.sub('[a-zA-Z]', '', s).strip() - # if len(res2) <= 0: # 表示s是纯英文 - # return 'en' - # re_words = re.compile(u"[\u4e00-\u9fa5]") - # res = re.findall(re_words, s) # 查询出所有的匹配字符串 - # print(res) - # res2 = re.sub(u"[\u4e00-\u9fa5]", '', s).strip() - # if len(res2) <= 0: # 表示s是纯中文 - # return 'zh-cn' - # return 'both' +def count_code(): + '''计算当前文件夹里面python代码的行数''' + files = os.listdir('.\\') + total = 0 + for file in files: + if not os.path.isfile(file): + continue + name, ext = os.path.splitext(file) + if ext != '.py': + continue + with open(file, 'r', encoding='utf-8') as f: + line = len(f.readlines()) + total += line + print("%s : %d" % (file, line)) + print("total :", total) -def pil2bytes(im, img_type='png', b64=False): - '''将PIL.Image格式的图像转化为二进制数据''' - bf = BytesIO() - im.save(bf, img_type) - img = bf.getvalue() - - return img if __name__ == '__main__': - while True: - s = input("输入:") - print(judgeLanguage(s)) + count_code() diff --git a/memorytools/xueersiOCR.py b/memorytools/xueersiOCR.py index fd1cb0a..7cb0d27 100644 --- a/memorytools/xueersiOCR.py +++ b/memorytools/xueersiOCR.py @@ -5,13 +5,14 @@ from base64 import b64encode from urllib.parse import quote from requests import post -from requests.exceptions import ConnectionError -from utils import * -from setting import * +from utils import pil2bytes +from setting import ALPHADIG, XUEERSI_ERROR_CODES + class XueersiOCR(object): ''' - 调用学而思AI平台的API进行OCR文字识别 + 调用学而思AI平台的API进行OCR识别。 + app_key, app_secret 需要到学而思开放平台的官网上登录获取。 ''' def __init__(self, app_key: str, app_secret: str): self.app_key = app_key @@ -19,14 +20,16 @@ def __init__(self, app_key: str, app_secret: str): self.start_time = 0 self.url = 'http://openapiai.xueersi.com/v1/api/img/ocr/general' - def ocr(self, image: str, img_type='base64')->dict: + def ocr(self, image: str, img_type='base64') -> dict: ''' - image 是base64字符串或者url + image: base64字符串或者url + img_type: 如果是 base64 字符串,则为 base64, 如果是 url,则为 url + 返回值: API返回的json ''' params = { - 'app_key' : self.app_key, - 'time_stamp' : str(int(time())), - 'nonce_str' : self.getNonceStr(), + 'app_key' : self.app_key, + 'time_stamp': str(int(time())), + 'nonce_str' : self.getNonceStr(), } params['sign'] = self.getReqSign(params, self.app_secret) params['img'] = image @@ -54,12 +57,12 @@ def join_params(self, params: dict)->str: ''' palist = [] for k, v in params.items(): - palist.append('%s=%s'%(k,v)) + palist.append('%s=%s' % (k, v)) payload = '&'.join(palist) return payload @classmethod - def getReqSign(self, params:dict, app_secret: str)->str: + def getReqSign(self, params: dict, app_secret: str) -> str: ''' 计算接口请求签名。 返回40位的16进制字符串。 @@ -72,7 +75,7 @@ def getReqSign(self, params:dict, app_secret: str)->str: return sign.hexdigest() @classmethod - def getNonceStr(self)->str: + def getNonceStr(self) -> str: ''' 返回一个长度为1~32的随机字符串。 ''' @@ -83,7 +86,12 @@ def getNonceStr(self)->str: class LatexOCR(object): - """docstring for LatexOCR""" + """ + 因为免费调用API的频率有限,因此构建一个多账号的OCR识别的类, + 可以提升程序处理的能力。 + accounts: 学而思AI平台的账号列表 + accounts = [{'app_key': '...', 'app_secret': '...'}, {...}, ...] + """ def __init__(self, accounts: list): # self.accounts = accounts self.interval = 10 @@ -93,8 +101,9 @@ def __init__(self, accounts: list): self.ocrs.append(XueersiOCR(acco['app_key'], acco['app_secret'])) def get_api(self): + '''返回一个接口用来进行OCR识别。''' xueersi = self.ocrs[self.index] - + time_pass = time() - xueersi.start_time if time_pass < self.interval: sleep(self.interval - time_pass + 0.1) @@ -102,15 +111,16 @@ def get_api(self): self.index = (self.index + 1) % len(self.ocrs) return xueersi - def ocr(self, image, img_type='base64'): + def ocr(self, image: str, img_type='base64'): + '''OCR识别的主函数,传入一个PIL.Image对象,返回识别的文本和位置。''' xueersi = self.get_api() res = xueersi.ocr(image, img_type) pos = [] code = res['code'] if code != 0: - if code in ERROR_CODES: - return (pos, ERROR_CODES[code]['reason']) + if code in XUEERSI_ERROR_CODES: + return (pos, XUEERSI_ERROR_CODES[code]['reason']) else: return (pos, "由于未知错误,识别失败!") @@ -123,7 +133,8 @@ def ocr(self, image, img_type='base64'): return (pos, content) - def latex(self, pilimg, img_type='base64'): + def latex(self, pilimg: Image, img_type='base64'): + '''OCR识别的主函数,传入一个PIL.Image对象,返回识别的文本和位置。''' if isinstance(pilimg, Image.Image): image = quote(b64encode(pil2bytes(pilimg))) From 53a052fff23d9c2c6690113ee7de9e3a1cbe3ff4 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Fri, 9 Oct 2020 16:54:40 +0800 Subject: [PATCH 03/28] v1.6.1 --- .idea/.gitignore | 3 + .idea/MemoryTools.iml | 8 ++ .../inspectionProfiles/profiles_settings.xml | 6 ++ .idea/misc.xml | 4 + .idea/modules.xml | 8 ++ .idea/vcs.xml | 6 ++ BUG.md | 47 ++++++++++ memorytools/__init__.py | 8 +- memorytools/boxes.py | 9 +- memorytools/config.json | 2 +- memorytools/copytrans.py | 87 ++++++++++++------ memorytools/memorytools.py | 1 + memorytools/ocr.py | 5 +- memorytools/setting.py | 1 + memorytools/trans/__init__.py | 0 memorytools/trans/base.py | 30 +++++++ memorytools/trans/urls.py | 15 ++++ memorytools/trans/youdao.py | 88 +++++++++++++++++++ memorytools/utils.py | 27 ++++++ memorytools/xueersiOCR.py | 4 +- 20 files changed, 317 insertions(+), 42 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/MemoryTools.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 BUG.md create mode 100644 memorytools/trans/__init__.py create mode 100644 memorytools/trans/base.py create mode 100644 memorytools/trans/urls.py create mode 100644 memorytools/trans/youdao.py diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/MemoryTools.iml b/.idea/MemoryTools.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/MemoryTools.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d1e22ec --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..ad39e5c --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/BUG.md b/BUG.md new file mode 100644 index 0000000..c718344 --- /dev/null +++ b/BUG.md @@ -0,0 +1,47 @@ +#### 开发日志 + +- 2020/3/26 + + - [ ] 发现bug1: + + ``` + Traceback (most recent call last): + File "memorytools.py", line 75, in + MemoryTool().run() + File "memorytools.py", line 69, in run + self.ct.start() + File "C:\Users\memory\OneDrive\code\MemoryTools\memorytools\copytrans.py", line 123, in start + self.trans(self.translator, source) + File "C:\Users\memory\OneDrive\code\MemoryTools\memorytools\copytrans.py", line 86, in trans + la, pro = judgeLanguage(source) + File "C:\Users\memory\OneDrive\code\MemoryTools\memorytools\utils.py", line 151, in judgeLanguage + return ('zh-cn', zh_num / total) + ZeroDivisionError: division by zero + ``` + + 原因分析:传入的字符串只有空格或换行,或者过滤掉特殊符号后只有空格或换行。 + + 解决:加入检测。 + + --- + + - [ ] 发现bug2: + + ``` + Traceback (most recent call last): + File "memorytools.py", line 75, in + MemoryTool().run() + File "memorytools.py", line 69, in run + self.ct.start() + File "C:\Users\memory\OneDrive\code\MemoryTools\memorytools\copytrans.py", line 122, in start + source = p.paste() # 获得剪切板内容 + File "C:\Users\memory\AppData\Local\Programs\Python\Python36\lib\site-packages\pyperclip\__init__.py", line 455, in paste_windows + with clipboard(None): + File "C:\Users\memory\AppData\Local\Programs\Python\Python36\lib\contextlib.py", line 81, in __enter__ + return next(self.gen) + File "C:\Users\memory\AppData\Local\Programs\Python\Python36\lib\site-packages\pyperclip\__init__.py", line 417, in clipboard + raise PyperclipWindowsException("Error calling OpenClipboard") + pyperclip.PyperclipWindowsException: Error calling OpenClipboard ([WinError 5] 拒绝访问。) + ``` + + \ No newline at end of file diff --git a/memorytools/__init__.py b/memorytools/__init__.py index 591a76b..edf6401 100644 --- a/memorytools/__init__.py +++ b/memorytools/__init__.py @@ -1,11 +1,11 @@ ''' @name: __init__ -@author: Memory&Xinxin +@author: Memory @date: 2020/03/20 ''' __title__ = 'memorytools' -__version__ = '1.0.1' -__author__ = 'Memory&Xinxin' -__copyright__ = 'Copyright 2020 Memory&Xinxin' +__version__ = '1.6.1' +__author__ = 'Memory' +__copyright__ = 'Copyright 2020 Memory' diff --git a/memorytools/boxes.py b/memorytools/boxes.py index 5279292..88add5a 100644 --- a/memorytools/boxes.py +++ b/memorytools/boxes.py @@ -4,13 +4,11 @@ @date: 2020/3/23 @description: 自定义的一些弹出框 ''' -import os -import pyperclip as p from PIL import ImageTk from tkinter import Tk, END from tkinter.ttk import Label, Button, Frame from tkinter.scrolledtext import ScrolledText, Text -from utils import getTextLine, resizeImg +from utils import getTextLine, resizeImg, getSrc, copyClip class BaseBox(Tk): @@ -25,8 +23,7 @@ def setWindow(self, title: str): self.screen_h = self.winfo_screenheight() self.title(title) self.resizable(False, False) - if os.path.exists("icon.ico"): - self.iconbitmap('icon.ico') + self.iconbitmap(getSrc('icon.ico')) min_w = self.screen_w // 3 min_h = self.screen_h // 3 @@ -60,7 +57,7 @@ def start(self, show=True): def copy(self): txt = self.textbox.get("1.0", END) - p.copy(txt) + copyClip(txt) self.destroy() diff --git a/memorytools/config.json b/memorytools/config.json index e298c54..b5b9ee9 100644 --- a/memorytools/config.json +++ b/memorytools/config.json @@ -1 +1 @@ -{"alert": {"is_alert": true, "alert_time": 60}, "copytrans": {"is_trans": true, "newline": false, "strict": false, "mode": "both", "src": "zh-cn", "dest": "en"}, "ocr": {"is_ocr": true, "newline": false, "mode": "formula"}} \ No newline at end of file +{"alert": {"is_alert": true, "alert_time": 90}, "copytrans": {"is_trans": true, "newline": false, "strict": false, "mode": "both", "src": "en", "dest": "zh-cn"}, "ocr": {"is_ocr": true, "newline": false, "mode": "text"}} \ No newline at end of file diff --git a/memorytools/copytrans.py b/memorytools/copytrans.py index 7f447aa..0b9f6cc 100644 --- a/memorytools/copytrans.py +++ b/memorytools/copytrans.py @@ -1,7 +1,7 @@ -import pyperclip as p from boxes import TextTextBox from googletransx import Translator -from utils import isCheckIcon, isPickIcon, judgeLanguage +from utils import isCheckIcon, isPickIcon, judgeLanguage, pasteClip, copyClip +from requests.exceptions import ConnectionError class CopyTrans(object): @@ -79,45 +79,80 @@ def turnNewline(self, sysTrayIcon): self.newline = not self.newline self.root.refreshMenu() - def trans(self, translator: Translator, source: str): - if source == "" or source == self.last: # 是否为空或者跟上次一样 - return None - - la, pro = judgeLanguage(source) - print('检测为:%s, %s. 目标语言为:%s'%(la, pro, self.dest)) - if self.mode != 'both' and la == self.dest and pro > 0.8: # 是否为纯目标语言 - self.last = source - return None - + def removeNewline(self, source): if not self.newline: - sentence = source.replace("\r", '').replace("\n", " ") # 去除换行符 + sentence = source.replace("\r", '').replace("\n", " ") else: sentence = source - sentence = sentence.strip() + return sentence + + def preProcess(self, source): + ''' + 对剪切板的文本进行预处理。 + 首先判断是否为空或者与上次复制的一致,如果是则不翻译。 + 然后检测语言,是否不包含中英文,如果是则不翻译。 + 再判断是否其中的目标语言占比过大,如果是则不翻译。 + 如果是互译模式,根据检测结果设置源语言和目标语言。 + 再判断是否要去除其中的换行。 + ''' + if source == "" or source == self.last: + return None + text = source.strip() + la, pro = judgeLanguage(text) + print('检测为:%s, %s. 目标语言为:%s'%(la, pro, self.dest)) + if not la: + self.last = source + return None + if self.mode != 'both' and la == self.dest and pro > 0.8: + self.last = source + return None if self.mode == 'both': self.src = la self.dest = 'en' if la == 'zh-cn' else 'zh-cn' - try: - if self.strict: - text = translator.translate(sentence, src=self.src, dest=self.dest).text # 翻译 - else: - text = translator.translate(sentence, dest=self.dest).text - except Exception as e: - text = str(e) - # 如果与原文本一样,则不显示 + sentence = self.removeNewline(text) + + return sentence + + def transText(self, sentence: str): + for i in range(3): + try: + if self.strict: + text = self.translator.translate(sentence, src=self.src, dest=self.dest).text + else: + text = self.translator.translate(sentence, dest=self.dest).text + return text + except ConnectionError as ce: + print(ce) + self.translator = Translator(service_urls=['translate.google.cn']) + text = str(ce) + except Exception as e: + print(e) + text = str(e) + return text + + def trans(self, source: str): + sentence = self.preProcess(source) + if not sentence: + return None + + text = self.transText(sentence) + if text == sentence: self.last = source print('译文与原文一致,因此不显示。') return None - # print("%s\n%s\n" % (sentence, text)) # 打印到命令行 + # print("%s\n%s\n" % (sentence, text)) TextTextBox('翻译结果').show(sentence, text) - self.last = p.paste() + # paste = pasteClip() + # if paste == source: + # copyClip(sentence) + self.last = pasteClip() def start(self): if not self.is_trans: # 是否暂停 return - source = p.paste() # 获得剪切板内容 - self.trans(self.translator, source) + source = pasteClip() # 获得剪切板内容 + self.trans(source) diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index d84b020..62265a4 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -11,6 +11,7 @@ class MemoryTool(object): '''程序的入口类''' + def __init__(self): self.icon = getSrc('icon.ico') config = readConfig() diff --git a/memorytools/ocr.py b/memorytools/ocr.py index 29c0b0d..1656a33 100644 --- a/memorytools/ocr.py +++ b/memorytools/ocr.py @@ -1,10 +1,9 @@ -import pyperclip as p from PIL import Image, ImageGrab, ImageDraw from baiduOCR import BaiduOCR from xueersiOCR import LatexOCR from boxes import ImageTextBox from setting import BAIDU_ACCOUNTS, XUEERSI_ACCOUNTS -from utils import isCheckIcon, isPickIcon, getRect, Color +from utils import isCheckIcon, isPickIcon, getRect, Color, copyClip class OCR(object): @@ -77,7 +76,7 @@ def start(self): except Exception as e: text = str(e) - p.copy('') + copyClip('') ImageTextBox('OCR识别结果').show(im, text) diff --git a/memorytools/setting.py b/memorytools/setting.py index 8bda5e9..83a0b9c 100644 --- a/memorytools/setting.py +++ b/memorytools/setting.py @@ -4,6 +4,7 @@ ABOUT_IMG = 'README.png' CONFIG = 'config.json' SRC_PATH = 'src' +LOG_PATH = 'log' ICONS = { 'icon.ico': ICON_ICO, 'trans.ico': TRANS_ICO, 'ocr.ico': OCR_ICO, 'alert.ico': ALERT_ICO, 'exit.ico': EXIT_ICO, 'about.ico': ABOUT_ICO, diff --git a/memorytools/trans/__init__.py b/memorytools/trans/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/memorytools/trans/base.py b/memorytools/trans/base.py new file mode 100644 index 0000000..b36acf0 --- /dev/null +++ b/memorytools/trans/base.py @@ -0,0 +1,30 @@ +import requests + + +class BaseTrans(object): + """docstring for BaseTrans""" + def __init__(self, url, mode='post'): + self.url = url + self.mode = mode + + @classmethod + def joinParams(self, params: dict) -> str: + ''' + 用于拼接参数。因为直接传递字典会返回图片模糊的结果,待解决。 + ''' + palist = [] + for k, v in params.items(): + palist.append('%s=%s' % (k, v)) + payload = '&'.join(palist) + return payload + + def getData(self, params: dict, headers=None): + payload = self.joinParams(params) + print(payload) + + res = requests.post(self.url, params=payload, headers=headers) + + return res.json() + + def translate(self, sentence: str, src: str, dest: str) -> str: + pass diff --git a/memorytools/trans/urls.py b/memorytools/trans/urls.py new file mode 100644 index 0000000..d89f33c --- /dev/null +++ b/memorytools/trans/urls.py @@ -0,0 +1,15 @@ +BAIDU_URL = 'http://fanyi.baidu.com/v2transapi' + +YOUDAO_URL = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule" + +GOOGLE_URL = 'https://translate.google.cn/translate_a/single' + +TENCENT_URL = 'http://fanyi.qq.com/api/translate' + +OMI_URL = 'http://www.omifanyi.com/transSents.do' + +TRYCAN_URL = 'http://fanyi.trycan.com/Transfer.do' + +ICIBA_URL = 'http://fy.iciba.com/ajax.php?a=fy' + +SOUGOU_URL = 'http://fanyi.sogou.com/reventondc/translate' diff --git a/memorytools/trans/youdao.py b/memorytools/trans/youdao.py new file mode 100644 index 0000000..066f892 --- /dev/null +++ b/memorytools/trans/youdao.py @@ -0,0 +1,88 @@ +from .base import BaseTrans +from .urls import YOUDAO_URL +from time import time +from random import randint +from hashlib import md5 + + +class YoudaoTrans(BaseTrans): + lang_map = {('zh-cn', 'en'): 'ZH_CH2EN', ('en', 'zh-cn'): 'EN2ZH_CH', + ('zh-cn', 'ja'): 'ZH_CN2JA', ('ja', 'zh-cn'): 'JA2ZH_CH', + ('zh-cn', 'kr'): 'ZH_CH2KR', ('kr', 'zh-cn'): 'KR2ZH_CH', + ('zh-cn', 'fr'): 'ZH_CN2FR', ('fr', 'zh-cn'): 'FR2ZH_CH', + ('zh-cn', 'ru'): 'ZH_CH2RU', ('ru', 'zh-cn'): 'RU2ZH_CH', + ('zh-cn', 'sp'): 'ZH_CN2SP', ('sp', 'zh-cn'): 'SP2ZH_CH'} + headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36', + # 'X-Requested-With': 'XMLHttpRequest', + "Referer": "http://fanyi.youdao.com/", + # 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', + "Cookie": "OUTFOX_SEARCH_USER_ID_NCOO=1674353290.232588;" + } + + def __init__(self): + super(YoudaoTrans, self).__init__(YOUDAO_URL) + + def constructParams(self, sentence, src, dest): + if (src, dest) in self.lang_map: + trans_type = self.langMap[(src, dest)] + else: + trans_type = 'AUTO' + + params = {'doctype': 'json', 'type': trans_type, 'i': sentence} + + return params + + def getParams(self, sentence, src, dest): + # src = src or 'AUTO' + # dest = dest or 'AUTO' + slat = str(int(time()*10000) + randint(1, 10)) + sign_text = "fanyideskweb" + sentence + slat + "ebSeFb%=XZ%T[KZ)c(sy!" + sign_text = sign_text.encode('utf-8') + sign = md5(sign_text).hexdigest() + + params = { + 'i': sentence, + 'from': src or 'AUTO', + 'to': dest or 'AUTO', + 'smartresult': 'dict', + 'client': 'fanyideskweb', + 'salt': slat, + 'sign': sign, + # 'ts': '1585286292515', + # 'bv': '70244e0061db49a9ee62d341c5fed82a', + 'doctype': 'json', + 'version': '2.1', + 'keyfrom': 'fanyi.web', + 'action': 'FY_BY_CLICKBUTTION', + "typoResult": "false", + } + return params + + def translate(self, sentence: str, src=None, dest=None) -> str: + params = self.getParams(sentence, src, dest) + print(params) + + res = self.getData(params, self.headers) + + return res + + # if 'errorCode' in res and res['errorCode'] != 0: + # return '未知错误,翻译失败!' + + # text_list = [] + # data_list = res['translateResult'] + # for data in data_list: + # text_list += data + + # text_list = [t['tgt'] for t in text_list] + # text = ' '.join(text_list) + # return text + + +if __name__ == '__main__': + t = YoudaoTrans().translate('你好') + print(t) + # while True: + # s = input('input: ') + # print(t.translate(s)) diff --git a/memorytools/utils.py b/memorytools/utils.py index 45d9239..f4b3d64 100644 --- a/memorytools/utils.py +++ b/memorytools/utils.py @@ -1,5 +1,7 @@ import os import re +from time import sleep +from pyperclip import paste, copy from json import dumps, loads from base64 import b64decode, b64encode from urllib.parse import quote @@ -18,6 +20,24 @@ def next(self): return color +def pasteClip(): + for i in range(3): + try: + text = paste() + return text + except Exception as e: + if i == 2: + return str(e) + sleep(0.1) + + +def copyClip(text): + try: + copy(text) + except Exception as e: + print(e) + + def getTextLine(text: str): '''返回所给的文本有几行''' return len(text.split('\n')) @@ -137,6 +157,9 @@ def judgeLanguage(sentence: str): '''判断一句话里面英文和中文的占比''' sentence = filterStr(sentence) + if sentence == '': + return (None, 0) + en_pattern = re.compile(u"[a-zA-Z]") zh_pattern = re.compile(u"[\u4e00-\u9fa5]") @@ -144,7 +167,11 @@ def judgeLanguage(sentence: str): zh = re.findall(zh_pattern, sentence) en_num = len(en) // 3 zh_num = len(zh) + total = en_num + zh_num + if total == 0: + return (None, 0) + if en_num > zh_num: return ('en', en_num / total) else: diff --git a/memorytools/xueersiOCR.py b/memorytools/xueersiOCR.py index 7cb0d27..d57d52c 100644 --- a/memorytools/xueersiOCR.py +++ b/memorytools/xueersiOCR.py @@ -36,7 +36,7 @@ def ocr(self, image: str, img_type='base64') -> dict: params['img_type'] = img_type params['recog_formula'] = 0 - payload = self.join_params(params) + payload = self.joinParams(params) headers = { 'Content-Type': "application/x-www-form-urlencoded", 'cache-control': "no-cache", @@ -51,7 +51,7 @@ def ocr(self, image: str, img_type='base64') -> dict: return res @classmethod - def join_params(self, params: dict)->str: + def joinParams(self, params: dict) -> str: ''' 用于拼接参数。因为直接传递字典会返回图片模糊的结果,待解决。 ''' From f2d0dea30e06f06978869c6099fbf84520f2f6ba Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Fri, 9 Oct 2020 18:44:07 +0800 Subject: [PATCH 04/28] v1.6.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 即时更改配置文件 --- .idea/MemoryTools.iml | 2 +- .idea/misc.xml | 2 +- memorytools/memorytools.py | 9 ++++++--- requirements.txt | 4 ++++ 4 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 requirements.txt diff --git a/.idea/MemoryTools.iml b/.idea/MemoryTools.iml index d0876a7..71589aa 100644 --- a/.idea/MemoryTools.iml +++ b/.idea/MemoryTools.iml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index d1e22ec..b458927 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index 62265a4..d3c74c1 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -47,15 +47,18 @@ def createMenu(self): def refreshMenu(self): '''创新菜单''' self.systray.refreshMenu(self.createMenu()) + self.refreshConfig() - def bye(self, sysTrayIcon: SysTrayIcon): - '''退出程序时将配置写到文件中''' - self.end = True + def refreshConfig(self): config = {} config['alert'] = self.alert.getConfig() config['copytrans'] = self.ct.getConfig() config['ocr'] = self.ocr.getConfig() writeConfig(config) + + def bye(self, sysTrayIcon: SysTrayIcon): + '''退出程序时将配置写到文件中''' + self.end = True print('bye') def run(self): diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..c9bc3c8 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +pillow +baidu-aip +pyperclip +googletransx \ No newline at end of file From 0e90832109a9e1996677135c354dc7441a0c8151 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Fri, 9 Oct 2020 19:06:49 +0800 Subject: [PATCH 05/28] v1.6.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更改代码结构 --- .idea/MemoryTools.iml | 2 +- memorytools/alert/__init__.py | 3 + memorytools/{ => alert}/alert.py | 0 memorytools/copytrans/__init__.py | 3 + memorytools/{ => copytrans}/copytrans.py | 0 memorytools/memorytools.py | 2 +- memorytools/ocr/__init__.py | 5 ++ memorytools/{ => ocr}/baiduOCR.py | 0 memorytools/{ => ocr}/ocr.py | 4 +- memorytools/{ => ocr}/xueersiOCR.py | 0 memorytools/trans/__init__.py | 0 memorytools/trans/base.py | 30 -------- memorytools/trans/urls.py | 15 ---- memorytools/trans/youdao.py | 88 ------------------------ requirements.txt | 3 +- 15 files changed, 17 insertions(+), 138 deletions(-) create mode 100644 memorytools/alert/__init__.py rename memorytools/{ => alert}/alert.py (100%) create mode 100644 memorytools/copytrans/__init__.py rename memorytools/{ => copytrans}/copytrans.py (100%) create mode 100644 memorytools/ocr/__init__.py rename memorytools/{ => ocr}/baiduOCR.py (100%) rename memorytools/{ => ocr}/ocr.py (97%) rename memorytools/{ => ocr}/xueersiOCR.py (100%) delete mode 100644 memorytools/trans/__init__.py delete mode 100644 memorytools/trans/base.py delete mode 100644 memorytools/trans/urls.py delete mode 100644 memorytools/trans/youdao.py diff --git a/.idea/MemoryTools.iml b/.idea/MemoryTools.iml index 71589aa..508668e 100644 --- a/.idea/MemoryTools.iml +++ b/.idea/MemoryTools.iml @@ -1,7 +1,7 @@ - + diff --git a/memorytools/alert/__init__.py b/memorytools/alert/__init__.py new file mode 100644 index 0000000..aaf415f --- /dev/null +++ b/memorytools/alert/__init__.py @@ -0,0 +1,3 @@ +from .alert import Alert + +__all__ = ["Alert"] diff --git a/memorytools/alert.py b/memorytools/alert/alert.py similarity index 100% rename from memorytools/alert.py rename to memorytools/alert/alert.py diff --git a/memorytools/copytrans/__init__.py b/memorytools/copytrans/__init__.py new file mode 100644 index 0000000..5282ffa --- /dev/null +++ b/memorytools/copytrans/__init__.py @@ -0,0 +1,3 @@ +from .copytrans import CopyTrans + +__all__ = ["CopyTrans"] diff --git a/memorytools/copytrans.py b/memorytools/copytrans/copytrans.py similarity index 100% rename from memorytools/copytrans.py rename to memorytools/copytrans/copytrans.py diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index d3c74c1..2616be2 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -57,7 +57,7 @@ def refreshConfig(self): writeConfig(config) def bye(self, sysTrayIcon: SysTrayIcon): - '''退出程序时将配置写到文件中''' + '''退出程序''' self.end = True print('bye') diff --git a/memorytools/ocr/__init__.py b/memorytools/ocr/__init__.py new file mode 100644 index 0000000..ff4a9b6 --- /dev/null +++ b/memorytools/ocr/__init__.py @@ -0,0 +1,5 @@ +from .baiduOCR import BaiduOCR +from .xueersiOCR import LatexOCR +from .ocr import OCR + +__all__ = ["BaiduOCR", "LatexOCR", "OCR"] diff --git a/memorytools/baiduOCR.py b/memorytools/ocr/baiduOCR.py similarity index 100% rename from memorytools/baiduOCR.py rename to memorytools/ocr/baiduOCR.py diff --git a/memorytools/ocr.py b/memorytools/ocr/ocr.py similarity index 97% rename from memorytools/ocr.py rename to memorytools/ocr/ocr.py index 1656a33..188b1d1 100644 --- a/memorytools/ocr.py +++ b/memorytools/ocr/ocr.py @@ -1,6 +1,6 @@ +from . import BaiduOCR +from . import LatexOCR from PIL import Image, ImageGrab, ImageDraw -from baiduOCR import BaiduOCR -from xueersiOCR import LatexOCR from boxes import ImageTextBox from setting import BAIDU_ACCOUNTS, XUEERSI_ACCOUNTS from utils import isCheckIcon, isPickIcon, getRect, Color, copyClip diff --git a/memorytools/xueersiOCR.py b/memorytools/ocr/xueersiOCR.py similarity index 100% rename from memorytools/xueersiOCR.py rename to memorytools/ocr/xueersiOCR.py diff --git a/memorytools/trans/__init__.py b/memorytools/trans/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/memorytools/trans/base.py b/memorytools/trans/base.py deleted file mode 100644 index b36acf0..0000000 --- a/memorytools/trans/base.py +++ /dev/null @@ -1,30 +0,0 @@ -import requests - - -class BaseTrans(object): - """docstring for BaseTrans""" - def __init__(self, url, mode='post'): - self.url = url - self.mode = mode - - @classmethod - def joinParams(self, params: dict) -> str: - ''' - 用于拼接参数。因为直接传递字典会返回图片模糊的结果,待解决。 - ''' - palist = [] - for k, v in params.items(): - palist.append('%s=%s' % (k, v)) - payload = '&'.join(palist) - return payload - - def getData(self, params: dict, headers=None): - payload = self.joinParams(params) - print(payload) - - res = requests.post(self.url, params=payload, headers=headers) - - return res.json() - - def translate(self, sentence: str, src: str, dest: str) -> str: - pass diff --git a/memorytools/trans/urls.py b/memorytools/trans/urls.py deleted file mode 100644 index d89f33c..0000000 --- a/memorytools/trans/urls.py +++ /dev/null @@ -1,15 +0,0 @@ -BAIDU_URL = 'http://fanyi.baidu.com/v2transapi' - -YOUDAO_URL = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule" - -GOOGLE_URL = 'https://translate.google.cn/translate_a/single' - -TENCENT_URL = 'http://fanyi.qq.com/api/translate' - -OMI_URL = 'http://www.omifanyi.com/transSents.do' - -TRYCAN_URL = 'http://fanyi.trycan.com/Transfer.do' - -ICIBA_URL = 'http://fy.iciba.com/ajax.php?a=fy' - -SOUGOU_URL = 'http://fanyi.sogou.com/reventondc/translate' diff --git a/memorytools/trans/youdao.py b/memorytools/trans/youdao.py deleted file mode 100644 index 066f892..0000000 --- a/memorytools/trans/youdao.py +++ /dev/null @@ -1,88 +0,0 @@ -from .base import BaseTrans -from .urls import YOUDAO_URL -from time import time -from random import randint -from hashlib import md5 - - -class YoudaoTrans(BaseTrans): - lang_map = {('zh-cn', 'en'): 'ZH_CH2EN', ('en', 'zh-cn'): 'EN2ZH_CH', - ('zh-cn', 'ja'): 'ZH_CN2JA', ('ja', 'zh-cn'): 'JA2ZH_CH', - ('zh-cn', 'kr'): 'ZH_CH2KR', ('kr', 'zh-cn'): 'KR2ZH_CH', - ('zh-cn', 'fr'): 'ZH_CN2FR', ('fr', 'zh-cn'): 'FR2ZH_CH', - ('zh-cn', 'ru'): 'ZH_CH2RU', ('ru', 'zh-cn'): 'RU2ZH_CH', - ('zh-cn', 'sp'): 'ZH_CN2SP', ('sp', 'zh-cn'): 'SP2ZH_CH'} - headers = { - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36', - # 'X-Requested-With': 'XMLHttpRequest', - "Referer": "http://fanyi.youdao.com/", - # 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', - "Cookie": "OUTFOX_SEARCH_USER_ID_NCOO=1674353290.232588;" - } - - def __init__(self): - super(YoudaoTrans, self).__init__(YOUDAO_URL) - - def constructParams(self, sentence, src, dest): - if (src, dest) in self.lang_map: - trans_type = self.langMap[(src, dest)] - else: - trans_type = 'AUTO' - - params = {'doctype': 'json', 'type': trans_type, 'i': sentence} - - return params - - def getParams(self, sentence, src, dest): - # src = src or 'AUTO' - # dest = dest or 'AUTO' - slat = str(int(time()*10000) + randint(1, 10)) - sign_text = "fanyideskweb" + sentence + slat + "ebSeFb%=XZ%T[KZ)c(sy!" - sign_text = sign_text.encode('utf-8') - sign = md5(sign_text).hexdigest() - - params = { - 'i': sentence, - 'from': src or 'AUTO', - 'to': dest or 'AUTO', - 'smartresult': 'dict', - 'client': 'fanyideskweb', - 'salt': slat, - 'sign': sign, - # 'ts': '1585286292515', - # 'bv': '70244e0061db49a9ee62d341c5fed82a', - 'doctype': 'json', - 'version': '2.1', - 'keyfrom': 'fanyi.web', - 'action': 'FY_BY_CLICKBUTTION', - "typoResult": "false", - } - return params - - def translate(self, sentence: str, src=None, dest=None) -> str: - params = self.getParams(sentence, src, dest) - print(params) - - res = self.getData(params, self.headers) - - return res - - # if 'errorCode' in res and res['errorCode'] != 0: - # return '未知错误,翻译失败!' - - # text_list = [] - # data_list = res['translateResult'] - # for data in data_list: - # text_list += data - - # text_list = [t['tgt'] for t in text_list] - # text = ' '.join(text_list) - # return text - - -if __name__ == '__main__': - t = YoudaoTrans().translate('你好') - print(t) - # while True: - # s = input('input: ') - # print(t.translate(s)) diff --git a/requirements.txt b/requirements.txt index c9bc3c8..bd0370f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ pillow baidu-aip pyperclip -googletransx \ No newline at end of file +googletransx +easydict From 620e0fc8335e7b89fc277acec03b94e7590bd367 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Fri, 9 Oct 2020 19:45:14 +0800 Subject: [PATCH 06/28] v1.6.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用EasyDict作为配置方式 --- memorytools/alert/alert.py | 52 +++++++--------- memorytools/config.json | 20 +++++- memorytools/copytrans/copytrans.py | 99 +++++++++++------------------- memorytools/memorytools.py | 20 +++--- memorytools/ocr/ocr.py | 60 +++++++----------- memorytools/setting.py | 62 ++++++++++--------- memorytools/utils.py | 17 ++--- 7 files changed, 153 insertions(+), 177 deletions(-) diff --git a/memorytools/alert/alert.py b/memorytools/alert/alert.py index fef0098..762ec86 100644 --- a/memorytools/alert/alert.py +++ b/memorytools/alert/alert.py @@ -1,75 +1,67 @@ from time import time + +from easydict import EasyDict + from boxes import LabelBox from setting import ALERT_MSG from utils import isCheckIcon, isPickIcon class Alert(object): - def __init__(self, root, wt=90): + def __init__(self, root, config): self.root = root - self.alert_time = wt - self.is_alert = True + self.config = config self.start_time = time() - def setConfig(self, config: dict): - if 'is_alert' in config: - self.is_alert = config['is_alert'] - if 'alert_time' in config: - self.alert_time = config['alert_time'] - - def getConfig(self) -> dict: - config = { - 'is_alert': self.is_alert, - 'alert_time': self.alert_time - } - return config + def getConfig(self) -> EasyDict: + return self.config def createMenu(self): menu_options = ( - ("开启提醒", isCheckIcon(self.is_alert), self.pauseAlert, True), - ('30分钟', isPickIcon(self.alert_time == 30), self.changeTime30, False), - ('60分钟', isPickIcon(self.alert_time == 60), self.changeTime60, False), - ('90分钟', isPickIcon(self.alert_time == 90), self.changeTime90, False), - ('120分钟', isPickIcon(self.alert_time == 120), self.changeTime120, False), + ("开启提醒", isCheckIcon(self.config.is_alert), self.pauseAlert, True), + ('30分钟', isPickIcon(self.config.alert_time == 30), self.changeTime30, False), + ('60分钟', isPickIcon(self.config.alert_time == 60), self.changeTime60, False), + ('90分钟', isPickIcon(self.config.alert_time == 90), self.changeTime90, False), + ('120分钟', isPickIcon(self.config.alert_time == 120), self.changeTime120, False), ) return menu_options def alert(self): minute = (time() - self.start_time) / 60 # 分钟数 - if minute >= self.alert_time: + if minute >= self.config.alert_time: return True return False def alertText(self): - return "关闭提醒" if self.is_alert else "开启提醒" + return "关闭提醒" if self.config.is_alert else "开启提醒" def pauseAlert(self, sysTrayIcon): - self.is_alert = not self.is_alert - if self.is_alert: + self.config.is_alert = not self.config.is_alert + if self.config.is_alert: self.start_time = time() else: LabelBox().show("虽然你关掉了休息提醒,但还是要注意身体!", '确认') self.root.refreshMenu() def changeTime30(self, sysTrayIcon): - self.alert_time = 30 + self.config.alert_time = 30 self.root.refreshMenu() def changeTime60(self, sysTrayIcon): - self.alert_time = 60 + self.config.alert_time = 60 self.root.refreshMenu() def changeTime90(self, sysTrayIcon): - self.alert_time = 90 + self.config.alert_time = 90 self.root.refreshMenu() def changeTime120(self, sysTrayIcon): - self.alert_time = 120 + self.config.alert_time = 120 self.root.refreshMenu() def start(self): - if self.is_alert and self.alert(): - alert_message = "你已经连续工作 %d 分钟了!是时候休息一下了!\n%s" % (self.alert_time, ALERT_MSG) + if self.config.is_alert and self.alert(): + alert_message = "你已经连续工作 %d 分钟了!是时候休息一下了!\n%s" % (self.config.alert_time, ALERT_MSG) LabelBox('危险警报').show(alert_message, '等你想要继续工作了再点我') self.start_time = time() diff --git a/memorytools/config.json b/memorytools/config.json index b5b9ee9..b162d37 100644 --- a/memorytools/config.json +++ b/memorytools/config.json @@ -1 +1,19 @@ -{"alert": {"is_alert": true, "alert_time": 90}, "copytrans": {"is_trans": true, "newline": false, "strict": false, "mode": "both", "src": "en", "dest": "zh-cn"}, "ocr": {"is_ocr": true, "newline": false, "mode": "text"}} \ No newline at end of file +{ + "alert": { + "is_alert": true, + "alert_time": 90 + }, + "copytrans": { + "is_trans": true, + "newline": false, + "strict": false, + "mode": "both", + "src": "en", + "dest": "zh-cn" + }, + "ocr": { + "is_ocr": true, + "newline": false, + "mode": "text" + } +} \ No newline at end of file diff --git a/memorytools/copytrans/copytrans.py b/memorytools/copytrans/copytrans.py index 0b9f6cc..36e4c7f 100644 --- a/memorytools/copytrans/copytrans.py +++ b/memorytools/copytrans/copytrans.py @@ -1,3 +1,5 @@ +from easydict import EasyDict + from boxes import TextTextBox from googletransx import Translator from utils import isCheckIcon, isPickIcon, judgeLanguage, pasteClip, copyClip @@ -5,82 +7,55 @@ class CopyTrans(object): - def __init__(self, root): + def __init__(self, root, config: EasyDict) -> None: self.root = root - self.is_trans = True - self.mode = 'both' - self.src = 'en' - self.dest = 'zh-cn' - self.strict = False - self.newline = False - self.last = '' # 记录上次的剪切板内容 - self.translator = Translator(service_urls=['translate.google.cn']) # 获得翻译接口 - - def setConfig(self, config: dict): - if 'is_trans' in config: - self.is_trans = config['is_trans'] - if 'newline' in config: - self.newline = config['newline'] - if 'strict' in config: - self.strict = config['strict'] - if 'mode' in config: - self.mode = config['mode'] - if 'src' in config: - self.src = config['src'] - if 'dest' in config: - self.dest = config['dest'] - - def getConfig(self) -> dict: - config = { - 'is_trans': self.is_trans, - 'newline': self.newline, - 'strict': self.strict, - 'mode': self.mode, - 'src': self.src, - 'dest': self.dest - } - return config + self.config = config + self.last = '' # 记录上次的剪切板内容 + self.translator = Translator(service_urls=['translate.google.cn']) # 获得翻译接口 + + def getConfig(self) -> EasyDict: + return self.config def createMenu(self) -> tuple: menu_options = ( - ("开启翻译", isCheckIcon(self.is_trans), self.pauseTrans, True), - ('去除换行', isCheckIcon(not self.newline), self.turnNewline, True), - ('严格模式', isCheckIcon(self.strict), self.turnStrict, True), - ('英文 <-> 中文', isPickIcon(self.mode=='both'), self.bothMode, False), - ('英文 --> 中文', isPickIcon(self.mode=='en2zh'), self.en2zhMode, False), - ('中文 --> 英文', isPickIcon(self.mode=='zh2en'), self.zh2enMode, False), - ) + ("开启翻译", isCheckIcon(self.config.is_trans), self.pauseTrans, True), + ('去除换行', isCheckIcon(not self.config.newline), self.turnNewline, True), + ('严格模式', isCheckIcon(self.config.strict), self.turnStrict, True), + ('英文 <-> 中文', isPickIcon(self.config.mode == 'both'), self.bothMode, False), + ('英文 --> 中文', isPickIcon(self.config.mode == 'en2zh'), self.en2zhMode, False), + ('中文 --> 英文', isPickIcon(self.config.mode == 'zh2en'), self.zh2enMode, False), + ) return menu_options def pauseTrans(self, sysTrayIcon): - self.is_trans = not self.is_trans + self.config.is_trans = not self.config.is_trans self.root.refreshMenu() def en2zhMode(self, sysTrayIcon): - self.mode = 'en2zh' - self.src, self.dest = 'en', 'zh-cn' + self.config.mode = 'en2zh' + self.config.src, self.config.dest = 'en', 'zh-cn' self.root.refreshMenu() def zh2enMode(self, sysTrayIcon): - self.mode = 'zh2en' - self.src, self.dest = 'zh-cn', 'en' + self.config.mode = 'zh2en' + self.config.src, self.config.dest = 'zh-cn', 'en' self.root.refreshMenu() def bothMode(self, sysTrayIcon): - self.mode = 'both' + self.config.mode = 'both' self.root.refreshMenu() def turnStrict(self, sysTrayIcon): - self.strict = not self.strict + self.config.strict = not self.config.strict self.root.refreshMenu() def turnNewline(self, sysTrayIcon): - self.newline = not self.newline + self.config.newline = not self.config.newline self.root.refreshMenu() def removeNewline(self, source): - if not self.newline: + if not self.config.newline: sentence = source.replace("\r", '').replace("\n", " ") else: sentence = source @@ -99,18 +74,18 @@ def preProcess(self, source): if source == "" or source == self.last: return None text = source.strip() - la, pro = judgeLanguage(text) - print('检测为:%s, %s. 目标语言为:%s'%(la, pro, self.dest)) - if not la: + src_language, score = judgeLanguage(text) + print('检测为:%s, %s. 目标语言为:%s' % (src_language, score, self.config.dest)) + if not src_language: self.last = source return None - if self.mode != 'both' and la == self.dest and pro > 0.8: + if self.config.mode != 'both' and src_language == self.config.dest and score > 0.8: self.last = source return None - if self.mode == 'both': - self.src = la - self.dest = 'en' if la == 'zh-cn' else 'zh-cn' + if self.config.mode == 'both': + self.config.src = src_language + self.config.dest = 'en' if src_language == 'zh-cn' else 'zh-cn' sentence = self.removeNewline(text) @@ -119,10 +94,10 @@ def preProcess(self, source): def transText(self, sentence: str): for i in range(3): try: - if self.strict: - text = self.translator.translate(sentence, src=self.src, dest=self.dest).text + if self.config.strict: + text = self.translator.translate(sentence, src=self.config.src, dest=self.config.dest).text else: - text = self.translator.translate(sentence, dest=self.dest).text + text = self.translator.translate(sentence, dest=self.config.dest).text return text except ConnectionError as ce: print(ce) @@ -152,7 +127,7 @@ def trans(self, source: str): self.last = pasteClip() def start(self): - if not self.is_trans: # 是否暂停 + if not self.config.is_trans: # 是否暂停 return - source = pasteClip() # 获得剪切板内容 + source = pasteClip() # 获得剪切板内容 self.trans(source) diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index 2616be2..d64c638 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -1,5 +1,8 @@ from PIL import Image from time import sleep + +from easydict import EasyDict + from ocr import OCR from alert import Alert from copytrans import CopyTrans @@ -15,12 +18,9 @@ class MemoryTool(object): def __init__(self): self.icon = getSrc('icon.ico') config = readConfig() - self.alert = Alert(self) - self.ct = CopyTrans(self) - self.ocr = OCR(self) - self.alert.setConfig(config['alert']) - self.ct.setConfig(config['copytrans']) - self.ocr.setConfig(config['ocr']) + self.alert = Alert(self, config.alert) + self.ct = CopyTrans(self, config.copytrans) + self.ocr = OCR(self, config.ocr) self.systray = SysTrayIcon(self.icon, HOVER_TEXT, self.createMenu(), on_quit=self.bye, default_menu_index=1, @@ -50,10 +50,10 @@ def refreshMenu(self): self.refreshConfig() def refreshConfig(self): - config = {} - config['alert'] = self.alert.getConfig() - config['copytrans'] = self.ct.getConfig() - config['ocr'] = self.ocr.getConfig() + config = EasyDict() + config.alert = self.alert.getConfig() + config.copytrans = self.ct.getConfig() + config.ocr = self.ocr.getConfig() writeConfig(config) def bye(self, sysTrayIcon: SysTrayIcon): diff --git a/memorytools/ocr/ocr.py b/memorytools/ocr/ocr.py index 188b1d1..046727e 100644 --- a/memorytools/ocr/ocr.py +++ b/memorytools/ocr/ocr.py @@ -1,3 +1,4 @@ +from easydict import EasyDict from . import BaiduOCR from . import LatexOCR from PIL import Image, ImageGrab, ImageDraw @@ -7,67 +8,52 @@ class OCR(object): - def __init__(self, root): + def __init__(self, root, config): self.root = root - self.is_ocr = True - self.newline = True - self.mode = 'text' + self.config = config self.textocr = BaiduOCR(BAIDU_ACCOUNTS) - self.formulaocr = LatexOCR(XUEERSI_ACCOUNTS) + self.mathocr = LatexOCR(XUEERSI_ACCOUNTS) - def setConfig(self, config: dict): - if 'is_ocr' in config: - self.is_ocr = config['is_ocr'] - if 'newline' in config: - self.newline = config['newline'] - if 'mode' in config: - self.mode = config['mode'] - - def getConfig(self) -> dict: - config = { - 'is_ocr': self.is_ocr, - 'newline': self.newline, - 'mode': self.mode - } - return config + def getConfig(self) -> EasyDict: + return self.config def createMenu(self) -> tuple: menu_options = ( - ("开启OCR", isCheckIcon(self.is_ocr), self.pauseOcr, True), - ('去除换行', isCheckIcon(not self.newline), self.turnNewline, True), - ('识别文本', isPickIcon(self.mode=='text'), self.textMode, False), - ('识别公式', isPickIcon(self.mode=='formula'), self.formulaMode, False), - ) + ("开启OCR", isCheckIcon(self.config.is_ocr), self.pauseOcr, True), + ('去除换行', isCheckIcon(not self.config.newline), self.turnNewline, True), + ('识别文本', isPickIcon(self.config.mode == 'text'), self.textMode, False), + ('识别公式', isPickIcon(self.config.mode == 'math'), self.mathMode, False), + ) return menu_options def pauseOcr(self, sysTrayIcon): - self.is_ocr = not self.is_ocr + self.config.is_ocr = not self.config.is_ocr self.root.refreshMenu() def textMode(self, sysTrayIcon): - self.mode = 'text' + self.config.mode = 'text' self.root.refreshMenu() - def formulaMode(self, sysTrayIcon): - self.mode = 'formula' + def mathMode(self, sysTrayIcon): + self.config.mode = 'math' self.root.refreshMenu() def turnNewline(self, sysTrayIcon): - self.newline = not self.newline + self.config.newline = not self.config.newline self.root.refreshMenu() def start(self): - if not self.is_ocr: + if not self.config.is_ocr: return - im = ImageGrab.grabclipboard() # 获取剪切板 + im = ImageGrab.grabclipboard() # 获取剪切板 - if isinstance(im, Image.Image): # 判断是否是图片 + if isinstance(im, Image.Image): # 判断是否是图片 try: - if self.mode == 'text': - text = self.textocr.ocr(im, self.newline) - elif self.mode == 'formula': - pos, text = self.formulaocr.latex(im) + if self.config.mode == 'text': + text = self.textocr.ocr(im, self.config.newline) + elif self.config.mode == 'math': + pos, text = self.mathocr.latex(im) print("位置:", pos) draw = ImageDraw.Draw(im) color = Color() diff --git a/memorytools/setting.py b/memorytools/setting.py index 83a0b9c..42743f5 100644 --- a/memorytools/setting.py +++ b/memorytools/setting.py @@ -1,4 +1,6 @@ from string import punctuation +from easydict import EasyDict + from pic import * ABOUT_IMG = 'README.png' @@ -6,10 +8,10 @@ SRC_PATH = 'src' LOG_PATH = 'log' ICONS = { - 'icon.ico': ICON_ICO, 'trans.ico': TRANS_ICO, 'ocr.ico': OCR_ICO, - 'alert.ico': ALERT_ICO, 'exit.ico': EXIT_ICO, 'about.ico': ABOUT_ICO, - 'check.ico': CHECK_ICO, 'pick.ico': PICK_ICO - } + 'icon.ico': ICON_ICO, 'trans.ico': TRANS_ICO, 'ocr.ico': OCR_ICO, + 'alert.ico': ALERT_ICO, 'exit.ico': EXIT_ICO, 'about.ico': ABOUT_ICO, + 'check.ico': CHECK_ICO, 'pick.ico': PICK_ICO +} HOVER_TEXT = "Memory Tools" ALERT_MSG = 'tip: 连续在电脑前工作太久容易脱发,得颈椎病,猝死。' @@ -42,6 +44,8 @@ } } +DEFAULT_CONFIG = EasyDict(DEFAULT_CONFIG) + # 学而思AI开方平台的账号 XUEERSI_ACCOUNTS = [ { @@ -130,7 +134,7 @@ 16109: {'reason': '此sid已经结束', 'solution': '当前sid服务端已经处理结束'}, 16110: {'reason': '此sid已经完全结束', 'solution': '当前sid服务端已经处理结束且触发超时,处于待清理状态'}, 16111: {'reason': '您传入的请求json中:common参数部分的sid属性长度不符合长度要求(16-64个字符)', 'solution': '请检查您的传入的sid是否符合要求的长度'} - } +} # 百度平台的错误码 BAIDU_ERROR_CODES = { @@ -142,7 +146,8 @@ 100: '无效参数', 110: 'Access Token失效', 111: 'Access token过期', - 282000: '服务器内部错误,如果您使用的是高精度接口,报这个错误码的原因可能是您上传的图片中文字过多,识别超时导致的,建议您对图片进行切割后再识别,其他情况请再次请求, 如果持续出现此类错误,请通过QQ群 (631977213)或工单联系技术支持团队。', + 282000: '服务器内部错误,如果您使用的是高精度接口,报这个错误码的原因可能是您上传的图片中文字过多,识别超时导致的,建议您对图片进行切割后再识别,其他情况请再次请求, 如果持续出现此类错误,请通过QQ群 ' + '(631977213)或工单联系技术支持团队。', 216100: '请求中包含非法参数,请检查后重新尝试', 216101: '缺少必须的参数,请检查参数是否有遗漏', 216102: '请求了不支持的服务,请检查调用的url', @@ -168,27 +173,26 @@ 282810: '图像识别错误' } - -LANGUAGE = {'自动检测':'', '中文':'zh-cn','中文繁体':'zh-tw', '英语':'en', '德语':'de', '俄语':'ru' ,'法语':'fr', - '阿尔巴尼亚语':'sq','阿拉伯语':'ar', '阿姆哈拉语':'am', '阿塞拜疆语':'az', '爱尔兰语':'ga', - '爱沙尼亚语':'et' ,'巴斯克语':'eu' ,'白俄罗斯语':'be', - '保加利亚语':'bg', '冰岛语':'is', '波兰语':'pl', '波斯尼亚语':'bs', - '波斯语':'fa', '布尔语':'af', '丹麦语':'da', - '菲律宾语':'tl', '芬兰语':'fi', '弗里西语':'fy' ,'高棉语':'km', '格鲁吉亚语':'ka', - '古吉拉特语':'gu', '哈萨克语':'kk', '海地克里奥尔语':'ht', - '豪萨语':'ha', '荷兰语':'nl' ,'吉尔吉斯语':'ky', '加利西亚语':'gl', '加泰罗尼亚语':'ca', - '捷克语':'cs', '卡纳达语':'kn', '科西嘉语':'co', '克罗地亚语':'hr', - '库尔德语':'ku', '拉丁语':'la', '拉脱维亚语':'lv', '老挝语':'lo', '立陶宛语':'lt', - '卢森堡语':'lb', '罗马尼亚语':'ro', '马尔加什语':'mg', '马耳他语':'mt', - '马拉地语':'mr', '马拉雅拉姆语':'mf', '马来语':'ms', '马其顿语':'mk', - '毛利语':'mi', '蒙古语':'mn','孟加拉语':'bn', '缅甸语':'my', '苗语':'hmn', '南非克萨语':'xh', '南非祖鲁语':'zu', - '尼泊尔语':'ne', '挪威语':'no', '旁遮普语' :'pa','葡萄牙语':'pt' ,'普什图语':'ps', - '齐切瓦语':'ny', '日语':'ja', '瑞典语':'sv', '萨摩亚语' :'sm','塞尔维亚语':'sr', - '赛所托语':'st','僧伽罗语':'si', '世界语':'eo', '斯洛伐克语':'sk', '斯洛文尼亚语':'sl', - '斯瓦希里语':'sw', '苏格兰盖尔语':'gd', '宿务语':'ceb', '索马里语':'so', '塔吉克语':'tg', '泰卢固语':'te', - '泰米尔语':'ta', '泰语':'th', '土耳其语':'tr', '威尔士语':'cy', '乌尔都语':'ur', - '乌克兰语':'uk', '乌兹别克语':'uz', '西班牙语':'es', '希伯来语':'rw', '希腊语':'el', - '夏威夷语':'haw', '信德语':'sd', '匈牙利语':'hu', '修纳语':'sn', - '亚美尼亚语':'hy', '伊博语':'ig', '意大利语':'it', '意第绪语':'yi', '印地语':'hi', - '印尼巽他':'su', '印尼语':'id', '印尼爪哇语':'jw', '约鲁巴语':'yo', '越南语':'vi' +LANGUAGE = {'自动检测': '', '中文': 'zh-cn', '中文繁体': 'zh-tw', '英语': 'en', '德语': 'de', '俄语': 'ru', '法语': 'fr', + '阿尔巴尼亚语': 'sq', '阿拉伯语': 'ar', '阿姆哈拉语': 'am', '阿塞拜疆语': 'az', '爱尔兰语': 'ga', + '爱沙尼亚语': 'et', '巴斯克语': 'eu', '白俄罗斯语': 'be', + '保加利亚语': 'bg', '冰岛语': 'is', '波兰语': 'pl', '波斯尼亚语': 'bs', + '波斯语': 'fa', '布尔语': 'af', '丹麦语': 'da', + '菲律宾语': 'tl', '芬兰语': 'fi', '弗里西语': 'fy', '高棉语': 'km', '格鲁吉亚语': 'ka', + '古吉拉特语': 'gu', '哈萨克语': 'kk', '海地克里奥尔语': 'ht', + '豪萨语': 'ha', '荷兰语': 'nl', '吉尔吉斯语': 'ky', '加利西亚语': 'gl', '加泰罗尼亚语': 'ca', + '捷克语': 'cs', '卡纳达语': 'kn', '科西嘉语': 'co', '克罗地亚语': 'hr', + '库尔德语': 'ku', '拉丁语': 'la', '拉脱维亚语': 'lv', '老挝语': 'lo', '立陶宛语': 'lt', + '卢森堡语': 'lb', '罗马尼亚语': 'ro', '马尔加什语': 'mg', '马耳他语': 'mt', + '马拉地语': 'mr', '马拉雅拉姆语': 'mf', '马来语': 'ms', '马其顿语': 'mk', + '毛利语': 'mi', '蒙古语': 'mn', '孟加拉语': 'bn', '缅甸语': 'my', '苗语': 'hmn', '南非克萨语': 'xh', '南非祖鲁语': 'zu', + '尼泊尔语': 'ne', '挪威语': 'no', '旁遮普语': 'pa', '葡萄牙语': 'pt', '普什图语': 'ps', + '齐切瓦语': 'ny', '日语': 'ja', '瑞典语': 'sv', '萨摩亚语': 'sm', '塞尔维亚语': 'sr', + '赛所托语': 'st', '僧伽罗语': 'si', '世界语': 'eo', '斯洛伐克语': 'sk', '斯洛文尼亚语': 'sl', + '斯瓦希里语': 'sw', '苏格兰盖尔语': 'gd', '宿务语': 'ceb', '索马里语': 'so', '塔吉克语': 'tg', '泰卢固语': 'te', + '泰米尔语': 'ta', '泰语': 'th', '土耳其语': 'tr', '威尔士语': 'cy', '乌尔都语': 'ur', + '乌克兰语': 'uk', '乌兹别克语': 'uz', '西班牙语': 'es', '希伯来语': 'rw', '希腊语': 'el', + '夏威夷语': 'haw', '信德语': 'sd', '匈牙利语': 'hu', '修纳语': 'sn', + '亚美尼亚语': 'hy', '伊博语': 'ig', '意大利语': 'it', '意第绪语': 'yi', '印地语': 'hi', + '印尼巽他': 'su', '印尼语': 'id', '印尼爪哇语': 'jw', '约鲁巴语': 'yo', '越南语': 'vi' } diff --git a/memorytools/utils.py b/memorytools/utils.py index f4b3d64..d5ea41f 100644 --- a/memorytools/utils.py +++ b/memorytools/utils.py @@ -1,11 +1,12 @@ import os import re +import json from time import sleep from pyperclip import paste, copy -from json import dumps, loads from base64 import b64decode, b64encode from urllib.parse import quote from io import BytesIO +from easydict import EasyDict from setting import COLOR, SRC_PATH, ICONS, CONFIG, DEFAULT_CONFIG, NOTAS, PUNCTUATION_MAP @@ -58,15 +59,15 @@ def pil2bytes(im, img_type='png', b64=False): def bs64toImg(pic_code, pic_name): - '''将bs64编码的数据写到文件中''' + """将bs64编码的数据写到文件中""" with open(pic_name, 'wb') as image: image.write(b64decode(pic_code)) def resizeImg(img, max_w: int, max_h: int): - ''' + """ 对img进行缩放,使其长宽不超过给定的 max_w 和 max_h - ''' + """ img_w, img_h = img.size if img_w < max_w and img_h < max_h: return img @@ -84,7 +85,7 @@ def resizeImg(img, max_w: int, max_h: int): def getSrc(pic: str): - '''返回对应资源的完整路径''' + """返回对应资源的完整路径""" path = os.path.join(SRC_PATH, pic) file = os.path.abspath(path) @@ -116,14 +117,14 @@ def img2base64(image: str): return image_data_base64 -def readConfig(name=CONFIG): +def readConfig(name=CONFIG) -> EasyDict: '''读配置文件''' if name == CONFIG and not os.path.exists(name): resetConfig() try: with open(name, "r") as f: data = f.read() - return loads(data) + return EasyDict(json.loads(data)) except Exception as e: print(e) return DEFAULT_CONFIG @@ -132,7 +133,7 @@ def readConfig(name=CONFIG): def writeConfig(data: dict, name=CONFIG): '''写配置文件''' try: - data = dumps(data) + data = json.dumps(data, indent=4) with open(name, "w") as f: f.write(data) except Exception as e: From a70b03aa3955395bdb5e031eea19edde44e5c3b4 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Fri, 9 Oct 2020 22:32:49 +0800 Subject: [PATCH 07/28] =?UTF-8?q?=E4=BD=BF=E7=94=A8plugin=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- memorytools/config.json | 10 +-- memorytools/memorytools.py | 75 +++++++++++-------- memorytools/plugins/__init__.py | 15 ++++ memorytools/{ => plugins}/alert/__init__.py | 2 +- memorytools/{ => plugins}/alert/alert.py | 16 ++-- memorytools/plugins/base.py | 19 +++++ .../{ => plugins}/copytrans/__init__.py | 2 +- .../{ => plugins}/copytrans/copytrans.py | 6 +- memorytools/{ => plugins}/ocr/__init__.py | 2 +- memorytools/{ => plugins}/ocr/baiduOCR.py | 0 memorytools/{ => plugins}/ocr/ocr.py | 6 +- memorytools/{ => plugins}/ocr/xueersiOCR.py | 0 memorytools/setting.py | 6 +- memorytools/utils.py | 34 ++++++--- 14 files changed, 124 insertions(+), 69 deletions(-) create mode 100644 memorytools/plugins/__init__.py rename memorytools/{ => plugins}/alert/__init__.py (56%) rename memorytools/{ => plugins}/alert/alert.py (84%) create mode 100644 memorytools/plugins/base.py rename memorytools/{ => plugins}/copytrans/__init__.py (58%) rename memorytools/{ => plugins}/copytrans/copytrans.py (97%) rename memorytools/{ => plugins}/ocr/__init__.py (67%) rename memorytools/{ => plugins}/ocr/baiduOCR.py (100%) rename memorytools/{ => plugins}/ocr/ocr.py (94%) rename memorytools/{ => plugins}/ocr/xueersiOCR.py (100%) diff --git a/memorytools/config.json b/memorytools/config.json index b162d37..e5bf1e7 100644 --- a/memorytools/config.json +++ b/memorytools/config.json @@ -1,9 +1,9 @@ { - "alert": { + "休息提醒": { "is_alert": true, - "alert_time": 90 + "alert_time": 60 }, - "copytrans": { + "复制翻译": { "is_trans": true, "newline": false, "strict": false, @@ -11,8 +11,8 @@ "src": "en", "dest": "zh-cn" }, - "ocr": { - "is_ocr": true, + "OCR识别": { + "is_ocr": false, "newline": false, "mode": "text" } diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index d64c638..dca383f 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -2,10 +2,9 @@ from time import sleep from easydict import EasyDict - -from ocr import OCR -from alert import Alert -from copytrans import CopyTrans +from plugins.ocr import OCR +from plugins.alert import Alert +from plugins.copytrans import CopyTrans from systray import SysTrayIcon from boxes import ImageBox from utils import getSrc, readConfig, writeConfig @@ -13,14 +12,18 @@ class MemoryTool(object): - '''程序的入口类''' + """ + 程序的入口类 + """ def __init__(self): self.icon = getSrc('icon.ico') config = readConfig() - self.alert = Alert(self, config.alert) - self.ct = CopyTrans(self, config.copytrans) - self.ocr = OCR(self, config.ocr) + + copytrans = CopyTrans(self, config) + ocr = OCR(self, config) + alert = Alert(self, config) + self.plugins = [copytrans, ocr, alert] self.systray = SysTrayIcon(self.icon, HOVER_TEXT, self.createMenu(), on_quit=self.bye, default_menu_index=1, @@ -30,39 +33,52 @@ def __init__(self): self.is_about = False self.end = False - def about(self, sysTrayIcon: SysTrayIcon): - '''菜单中的 关于 选项,如果在线程中调用会出错,因此用一个变量控制,在主线程中显示信息''' + def about(self, s: SysTrayIcon): + """ + 菜单中的 关于 选项,如果在线程中调用会出错,因此用一个变量控制,在主线程中显示信息 + """ self.is_about = True def createMenu(self): - '''创建托盘程序的菜单''' - self.menu_options = ( - ('复制翻译', getSrc('trans.ico'), self.ct.createMenu(), True), - ('OCR识别', getSrc('ocr.ico'), self.ocr.createMenu(), True), - ('休息提醒', getSrc('alert.ico'), self.alert.createMenu(), True), - ('关于', getSrc('about.ico'), self.about, True), - ) - return self.menu_options + """创建托盘程序的菜单 + 菜单中的每一项为元组,每个元组含义如下: + 第 1 项:菜单项名称 + 第 2 项:图标路径 + 第 3 项:可以递归嵌套子菜单,如果没有子菜单则为回调函数 + 第 4 项:表示该项菜单后面是否有一条分割线 + """ + menu_options = [] + for plugin in self.plugins: + menu_options.append(plugin.initMenu()) + menu_options.append(('关于', getSrc('about.ico'), self.about, True)) + + return tuple(menu_options) def refreshMenu(self): - '''创新菜单''' + """ + 刷新菜单 + """ self.systray.refreshMenu(self.createMenu()) self.refreshConfig() - def refreshConfig(self): - config = EasyDict() - config.alert = self.alert.getConfig() - config.copytrans = self.ct.getConfig() - config.ocr = self.ocr.getConfig() + def refreshConfig(self) -> None: + """ + 写入设置 + """ + config = {} + for plugin in self.plugins: + name, con = plugin.getConfig() + config[name] = con + writeConfig(config) - def bye(self, sysTrayIcon: SysTrayIcon): - '''退出程序''' + def bye(self, s: SysTrayIcon): + """退出程序""" self.end = True print('bye') def run(self): - '''启动''' + """启动""" self.systray.start() while not self.end: sleep(0.1) @@ -70,9 +86,8 @@ def run(self): self.is_about = False img = Image.open(getSrc(ABOUT_IMG)) ImageBox('Memory Tools').show(img) - self.ct.start() - self.alert.start() - self.ocr.start() + for plugin in self.plugins: + plugin.start() if __name__ == '__main__': diff --git a/memorytools/plugins/__init__.py b/memorytools/plugins/__init__.py new file mode 100644 index 0000000..81a9eeb --- /dev/null +++ b/memorytools/plugins/__init__.py @@ -0,0 +1,15 @@ +from pathlib import Path +from .base import BasePlugin + + +plugin_path = Path() / "plugins" + +all_plugins = [] +for d in plugin_path.iterdir(): + if d.is_dir() and d.name != "__pycache__": + all_plugins.append(__import__("plugins."+d.name)) + + +print(all_plugins) + + diff --git a/memorytools/alert/__init__.py b/memorytools/plugins/alert/__init__.py similarity index 56% rename from memorytools/alert/__init__.py rename to memorytools/plugins/alert/__init__.py index aaf415f..cdebfc6 100644 --- a/memorytools/alert/__init__.py +++ b/memorytools/plugins/alert/__init__.py @@ -1,3 +1,3 @@ from .alert import Alert -__all__ = ["Alert"] +__all__ = [Alert] diff --git a/memorytools/alert/alert.py b/memorytools/plugins/alert/alert.py similarity index 84% rename from memorytools/alert/alert.py rename to memorytools/plugins/alert/alert.py index 762ec86..2e36418 100644 --- a/memorytools/alert/alert.py +++ b/memorytools/plugins/alert/alert.py @@ -1,16 +1,14 @@ from time import time - from easydict import EasyDict - from boxes import LabelBox from setting import ALERT_MSG from utils import isCheckIcon, isPickIcon +from plugins import BasePlugin -class Alert(object): - def __init__(self, root, config): - self.root = root - self.config = config +class Alert(BasePlugin): + def __init__(self, root, config) -> None: + super(Alert, self).__init__("休息提醒", root, 'alert.ico', config) self.start_time = time() def getConfig(self) -> EasyDict: @@ -33,15 +31,13 @@ def alert(self): return True return False - def alertText(self): - return "关闭提醒" if self.config.is_alert else "开启提醒" - def pauseAlert(self, sysTrayIcon): self.config.is_alert = not self.config.is_alert if self.config.is_alert: self.start_time = time() else: - LabelBox().show("虽然你关掉了休息提醒,但还是要注意身体!", '确认') + print("虽然你关掉了休息提醒,但还是要注意身体!") + # LabelBox().show("虽然你关掉了休息提醒,但还是要注意身体!", "确定") self.root.refreshMenu() def changeTime30(self, sysTrayIcon): diff --git a/memorytools/plugins/base.py b/memorytools/plugins/base.py new file mode 100644 index 0000000..88249ca --- /dev/null +++ b/memorytools/plugins/base.py @@ -0,0 +1,19 @@ +from easydict import EasyDict +from utils import getSrc + + +class BasePlugin(object): + def __init__(self, name: str, root, icon: str, config: EasyDict): + self.name = name + self.root = root + self.icon = icon + self.config = config[name] + + def getConfig(self) -> EasyDict: + return self.name, self.config + + def createMenu(self) -> tuple: + return () + + def initMenu(self) -> tuple: + return self.name, getSrc(self.icon), self.createMenu(), True diff --git a/memorytools/copytrans/__init__.py b/memorytools/plugins/copytrans/__init__.py similarity index 58% rename from memorytools/copytrans/__init__.py rename to memorytools/plugins/copytrans/__init__.py index 5282ffa..041973a 100644 --- a/memorytools/copytrans/__init__.py +++ b/memorytools/plugins/copytrans/__init__.py @@ -1,3 +1,3 @@ from .copytrans import CopyTrans -__all__ = ["CopyTrans"] +__all__ = [CopyTrans] diff --git a/memorytools/copytrans/copytrans.py b/memorytools/plugins/copytrans/copytrans.py similarity index 97% rename from memorytools/copytrans/copytrans.py rename to memorytools/plugins/copytrans/copytrans.py index 36e4c7f..35b723d 100644 --- a/memorytools/copytrans/copytrans.py +++ b/memorytools/plugins/copytrans/copytrans.py @@ -4,12 +4,12 @@ from googletransx import Translator from utils import isCheckIcon, isPickIcon, judgeLanguage, pasteClip, copyClip from requests.exceptions import ConnectionError +from plugins import BasePlugin -class CopyTrans(object): +class CopyTrans(BasePlugin): def __init__(self, root, config: EasyDict) -> None: - self.root = root - self.config = config + super(CopyTrans, self).__init__("复制翻译", root, "trans.ico", config) self.last = '' # 记录上次的剪切板内容 self.translator = Translator(service_urls=['translate.google.cn']) # 获得翻译接口 diff --git a/memorytools/ocr/__init__.py b/memorytools/plugins/ocr/__init__.py similarity index 67% rename from memorytools/ocr/__init__.py rename to memorytools/plugins/ocr/__init__.py index ff4a9b6..0072094 100644 --- a/memorytools/ocr/__init__.py +++ b/memorytools/plugins/ocr/__init__.py @@ -2,4 +2,4 @@ from .xueersiOCR import LatexOCR from .ocr import OCR -__all__ = ["BaiduOCR", "LatexOCR", "OCR"] +__all__ = [BaiduOCR, LatexOCR, OCR] diff --git a/memorytools/ocr/baiduOCR.py b/memorytools/plugins/ocr/baiduOCR.py similarity index 100% rename from memorytools/ocr/baiduOCR.py rename to memorytools/plugins/ocr/baiduOCR.py diff --git a/memorytools/ocr/ocr.py b/memorytools/plugins/ocr/ocr.py similarity index 94% rename from memorytools/ocr/ocr.py rename to memorytools/plugins/ocr/ocr.py index 046727e..56d0118 100644 --- a/memorytools/ocr/ocr.py +++ b/memorytools/plugins/ocr/ocr.py @@ -5,12 +5,12 @@ from boxes import ImageTextBox from setting import BAIDU_ACCOUNTS, XUEERSI_ACCOUNTS from utils import isCheckIcon, isPickIcon, getRect, Color, copyClip +from plugins import BasePlugin -class OCR(object): +class OCR(BasePlugin): def __init__(self, root, config): - self.root = root - self.config = config + super(OCR, self).__init__("OCR识别", root, "ocr.ico", config) self.textocr = BaiduOCR(BAIDU_ACCOUNTS) self.mathocr = LatexOCR(XUEERSI_ACCOUNTS) diff --git a/memorytools/ocr/xueersiOCR.py b/memorytools/plugins/ocr/xueersiOCR.py similarity index 100% rename from memorytools/ocr/xueersiOCR.py rename to memorytools/plugins/ocr/xueersiOCR.py diff --git a/memorytools/setting.py b/memorytools/setting.py index 42743f5..c6cefe3 100644 --- a/memorytools/setting.py +++ b/memorytools/setting.py @@ -22,7 +22,7 @@ NOTAS = u'[’·°–!"#$%&\'()*+,-./:;<=>?@,。?★、…【】()《》?“”‘’![\\]^_`{|}~]+' DEFAULT_CONFIG = { - 'copytrans': + '复制翻译': { 'is_trans': True, 'newline': False, @@ -31,13 +31,13 @@ 'src': 'en', 'dest': 'zh-cn' }, - 'ocr': + 'OCR识别': { 'is_ocr': True, 'newline': True, 'mode': 'text' }, - 'alert': + '休息提醒': { 'is_alert': True, 'alert_time': 90 diff --git a/memorytools/utils.py b/memorytools/utils.py index d5ea41f..c7a950d 100644 --- a/memorytools/utils.py +++ b/memorytools/utils.py @@ -118,11 +118,13 @@ def img2base64(image: str): def readConfig(name=CONFIG) -> EasyDict: - '''读配置文件''' + """ + 读配置文件 + """ if name == CONFIG and not os.path.exists(name): resetConfig() try: - with open(name, "r") as f: + with open(name, "r", encoding="utf-8") as f: data = f.read() return EasyDict(json.loads(data)) except Exception as e: @@ -131,22 +133,28 @@ def readConfig(name=CONFIG) -> EasyDict: def writeConfig(data: dict, name=CONFIG): - '''写配置文件''' + """ + 写配置文件 + """ try: - data = json.dumps(data, indent=4) - with open(name, "w") as f: + data = json.dumps(data, indent=4, ensure_ascii=False) + with open(name, "w", encoding="utf-8") as f: f.write(data) except Exception as e: print(e) def resetConfig(name=CONFIG): - '''重置配置文件''' + """ + 重置配置文件 + """ writeConfig(DEFAULT_CONFIG, name) def filterStr(sentence: str): - '''过滤掉字符串中的标点符号''' + """ + 过滤掉字符串中的标点符号 + """ sentence = re.sub(NOTAS, '', sentence) sentence = sentence.translate(PUNCTUATION_MAP) sentence = re.sub('[0-9]', '', sentence).strip() @@ -155,7 +163,9 @@ def filterStr(sentence: str): def judgeLanguage(sentence: str): - '''判断一句话里面英文和中文的占比''' + """ + 判断一句话里面英文和中文的占比 + """ sentence = filterStr(sentence) if sentence == '': @@ -171,16 +181,16 @@ def judgeLanguage(sentence: str): total = en_num + zh_num if total == 0: - return (None, 0) + return None, 0 if en_num > zh_num: - return ('en', en_num / total) + return 'en', en_num / total else: - return ('zh-cn', zh_num / total) + return 'zh-cn', zh_num / total def count_code(): - '''计算当前文件夹里面python代码的行数''' + """计算当前文件夹里面python代码的行数""" files = os.listdir('.\\') total = 0 for file in files: From 196a1a97efa6700391632a03989d02dbe947af92 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Fri, 9 Oct 2020 23:45:35 +0800 Subject: [PATCH 08/28] =?UTF-8?q?=E6=9B=B4=E6=94=B9config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- memorytools/{setting.py => globals.py} | 39 +++++-- memorytools/memorytools.py | 42 +++---- memorytools/pic.py | 8 -- memorytools/plugins/alert/alert.py | 18 +-- memorytools/plugins/base.py | 5 +- memorytools/plugins/copytrans/copytrans.py | 5 +- memorytools/plugins/ocr/baiduOCR.py | 2 +- memorytools/plugins/ocr/ocr.py | 6 +- memorytools/plugins/ocr/xueersiOCR.py | 2 +- memorytools/tools/__init__.py | 0 memorytools/{ => tools}/boxes.py | 5 +- memorytools/tools/config.py | 23 ++++ memorytools/{ => tools}/systray/__init__.py | 0 .../{ => tools}/systray/__version__.py | 0 memorytools/{ => tools}/systray/traybar.py | 0 .../{ => tools}/systray/win32_adapter.py | 0 memorytools/utils.py | 106 +++++++++--------- 18 files changed, 145 insertions(+), 119 deletions(-) rename memorytools/{setting.py => globals.py} (95%) delete mode 100644 memorytools/pic.py create mode 100644 memorytools/tools/__init__.py rename memorytools/{ => tools}/boxes.py (98%) create mode 100644 memorytools/tools/config.py rename memorytools/{ => tools}/systray/__init__.py (100%) rename memorytools/{ => tools}/systray/__version__.py (100%) rename memorytools/{ => tools}/systray/traybar.py (100%) rename memorytools/{ => tools}/systray/win32_adapter.py (100%) diff --git a/.gitignore b/.gitignore index b39f873..88c319c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ memorytools.egg-info/ test/ src/ memorytools/__pycache__/ -upx-3.95-win64/ \ No newline at end of file +upx-3.95-win64/ +.idea/ \ No newline at end of file diff --git a/memorytools/setting.py b/memorytools/globals.py similarity index 95% rename from memorytools/setting.py rename to memorytools/globals.py index c6cefe3..3919087 100644 --- a/memorytools/setting.py +++ b/memorytools/globals.py @@ -1,20 +1,35 @@ from string import punctuation from easydict import EasyDict +from pathlib import Path +# from src.src import * -from pic import * -ABOUT_IMG = 'README.png' -CONFIG = 'config.json' -SRC_PATH = 'src' -LOG_PATH = 'log' -ICONS = { - 'icon.ico': ICON_ICO, 'trans.ico': TRANS_ICO, 'ocr.ico': OCR_ICO, - 'alert.ico': ALERT_ICO, 'exit.ico': EXIT_ICO, 'about.ico': ABOUT_ICO, - 'check.ico': CHECK_ICO, 'pick.ico': PICK_ICO -} +class PATH: + cwd = Path() + icon = cwd / 'src' / 'icon' + config = cwd / 'config.json' + log = cwd / 'log' + + +class TEXT: + hover = "Memory Tools" + alert = '你已经连续工作 %d 分钟了!是时候休息一下了!\ntip: 连续在电脑前工作太久容易脱发,得颈椎病,猝死。' + + +ICON = EasyDict() +for ico in PATH.icon.glob("*.ico"): + ICON[ico.stem] = str(ico) + + +# ABOUT_IMG = 'README.png' +# +# ICONS = { +# 'icon.ico': ICON_ICO, 'trans.ico': TRANS_ICO, 'ocr.ico': OCR_ICO, +# 'alert.ico': ALERT_ICO, 'exit.ico': EXIT_ICO, 'about.ico': ABOUT_ICO, +# 'check.ico': CHECK_ICO, 'pick.ico': PICK_ICO +# } + -HOVER_TEXT = "Memory Tools" -ALERT_MSG = 'tip: 连续在电脑前工作太久容易脱发,得颈椎病,猝死。' ALPHADIG = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' COLOR = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 0, 255), (0, 255, 255)] diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index dca383f..9085cf6 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -1,14 +1,13 @@ +import webbrowser from PIL import Image from time import sleep - -from easydict import EasyDict from plugins.ocr import OCR from plugins.alert import Alert from plugins.copytrans import CopyTrans -from systray import SysTrayIcon -from boxes import ImageBox -from utils import getSrc, readConfig, writeConfig -from setting import HOVER_TEXT, ABOUT_IMG +from tools.systray import SysTrayIcon +from tools.config import Config +from tools.boxes import ImageBox +from globals import TEXT, ICON class MemoryTool(object): @@ -17,28 +16,21 @@ class MemoryTool(object): """ def __init__(self): - self.icon = getSrc('icon.ico') - config = readConfig() - + self.icon = ICON.icon + self.config = Config() + config = self.config.readConfig() copytrans = CopyTrans(self, config) ocr = OCR(self, config) alert = Alert(self, config) self.plugins = [copytrans, ocr, alert] - self.systray = SysTrayIcon(self.icon, HOVER_TEXT, self.createMenu(), + self.systray = SysTrayIcon(self.icon, TEXT.hover, self.createMenu(), on_quit=self.bye, default_menu_index=1, - exit_ico=getSrc('exit.ico') + exit_ico=ICON.exit ) - self.is_about = False self.end = False - def about(self, s: SysTrayIcon): - """ - 菜单中的 关于 选项,如果在线程中调用会出错,因此用一个变量控制,在主线程中显示信息 - """ - self.is_about = True - def createMenu(self): """创建托盘程序的菜单 菜单中的每一项为元组,每个元组含义如下: @@ -50,7 +42,7 @@ def createMenu(self): menu_options = [] for plugin in self.plugins: menu_options.append(plugin.initMenu()) - menu_options.append(('关于', getSrc('about.ico'), self.about, True)) + menu_options.append(('关于', ICON.about, self.about, True)) return tuple(menu_options) @@ -70,7 +62,13 @@ def refreshConfig(self) -> None: name, con = plugin.getConfig() config[name] = con - writeConfig(config) + self.config.writeConfig(config) + + def about(self, s: SysTrayIcon): + """ + 菜单中的 关于 选项,如果在线程中调用会出错,因此用一个变量控制,在主线程中显示信息 + """ + webbrowser.open("https://github.com/MemoryD/MemoryTools") def bye(self, s: SysTrayIcon): """退出程序""" @@ -82,10 +80,6 @@ def run(self): self.systray.start() while not self.end: sleep(0.1) - if self.is_about: - self.is_about = False - img = Image.open(getSrc(ABOUT_IMG)) - ImageBox('Memory Tools').show(img) for plugin in self.plugins: plugin.start() diff --git a/memorytools/pic.py b/memorytools/pic.py deleted file mode 100644 index 7bf5e7a..0000000 --- a/memorytools/pic.py +++ /dev/null @@ -1,8 +0,0 @@ -ICON_ICO = "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8f9dr/X/Zrr8/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2m9/f9Wp/D/RpTl/5CNmP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/YpDH/0WT5f9Fk+X/RZPl4ESS5BoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEST5ZFFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/1+y9/9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9ysuf/xYlj/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/7aKcv9FkuT/RZPl/0WT5f9Fk+X/RZLkzESS5AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEk+RbRZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/Xa71/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///6ecmP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/do+y/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RJLklwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJLlGUWT5e9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9YqfL/a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///98tOH/yIlh/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/7KKdv9GkuP/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X+RJLkRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFkuWgRZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f5Ek+TaRJPlrUST5ZVFk+WSRJLkpUST5MxFk+T6RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/1Oj7/9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///66YjP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/bY+8/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+XbRJLkBgAAAAAAAAAAAAAAAAAAAAAAAAAARJLlJUWT5fxFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WS5epEk+V8RJPlHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEST4xBEk+RlRZPl2EWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/TZzq/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///+Dsdb/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/6qLfv9Fk+T/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Ek+VuAAAAAAAAAAAAAAAAAAAAAAAAAABEkuWQRZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Ek+SfRJLlDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEkuQERJPkeUWT5ftFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9GlOX/ar7+/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a77+/7SUgv/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/IiWD/ZJDF/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0ST5eNEk+UFAAAAAAAAAAAAAAAARJPkA0SS5elFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RJLkfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJLlS0WT5fhFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9itfn/a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///+Jrcr/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/6CMiP9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5VgAAAAAAAAAAAAAAABDk+U5RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0SS5KUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJPlYkWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/1ip8v9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///bL78/7qReP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/HiWH/W5HO/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RJLkugAAAAAAAAAAAAAAAEST5XdFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Ek+TzQ5HjFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJLluEWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/TJvq/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///+Qqb//yYlg/8mJYP/JiWD/yIlg/7mKcP+si3z/q4t9/7SKdP/EiWX/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/5eMkv9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X7RZPkEwAAAAAAAAAARJLkpUWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0ST5ZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEkuQ4RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/Zbj7/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///brz4/7+OcP/JiWD/wYln/3+Oqf9Qktn/RZPl/0WT5f9Fk+X/RZPl/0WS5P9ZkdD/eo6v/6OLhv/GiWL/yYlg/8mJYP/FiWT/VJHV/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+VaAAAAAAAAAABEkuTGRZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RJPkVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAESS5SZFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Wp/H/a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///+XpbT/yYlg/8eJYf9gkcn/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/1OR1v+NjZv/xIlk/42Nm/9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0ST5ZoAAAAAAAAAAEWS5dtFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9EkuQrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJPkWEWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0iW5/9pvf7/a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///cbvz/8OM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+v9Wpvr/Vqb6/1am+v9Wpvr/os78//3+/v/////////////////////////////////////////////////////////////////RnHn/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/IiF8sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADJiGCPyYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/ny7n/////////////////////////////////////////////////9ff6/9vk7f/v8/f//////+Tx/v9jrPr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9LluX/MW+w/yJZk/8iWZL/IlmS/yJZkv8iWZL/IlmS/yJZkv8iWZL/IlmS/yJZkv8jW5X/OnzC/1Sj9/9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/6XQ/P////////////z9/v/f5+//5Ovy//7+/v///////////////////////////////////////////9Off//JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8iJXzQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMmJYJPJiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/+jMu///////////////////////////////////////9/n7/36dv/8oXJT/IliS/yNZkv9ojbT/6/D1/9Dm/f9Wpvr/Vqb6/1am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/v9HdKT/IliS/yJYkv8iWJL/IliS/yJYkv8iWJL/bpG3////////////////////////////9enh/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yIhf6wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMiIXy3JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8qMZf/+/fz/////////////////////////////////iKXE/yJYkv8iWJL/IliS/yJYkv8iWJL/Y4my//3+/v//////5PH+/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/mcn8/////////////////8nW5P8oXJX/IliS/yJYkv8iWJL/IliS/zVmm//j6vH////////////////////////////s1cf/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiF/JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAx4dgCcmJX/3JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg//Xq4v/////////////////////////////////+/v7/qL3U/0h1pf8nXJT/Pm2g/5Ksyf/5+/z////////////m8v7/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v+ayvz//////////////////////9Lc6P9fhrD/LF+W/zBjmf9vkrj/4+rx/////////////////////////////////+G+p//JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8iIX6YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyYlf3MmJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/6c++/////////////////////////////////////////////////////////////////////////////////9rr/f9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/47D+///////////////////////////////////////////////////////////////////////////////////////1KKD/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yIlfegAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIiF+ryYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/ar5T/////////////////////////////////////////////////////////////////////////////////vdz9/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/cbT6//////////////////////////////////////////////////////////////////////////////////v39P/JimL/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/IiV9LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMiIX3LJiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8yQaf/9/Pv///////////////////////////////////////////////////////////////////////////+Rxfv/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/7fX+////////////////////////////////////////////////////////////////////////////7NbI/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/siIXxMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyIhfNsmJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/+7bz///////////////////////////////////////////////////////////////////////9fn+/12q+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v+x1vz////////////////////////////////////////////////////////////////////////////ar5P/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/IiGDWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIiV4DyYhg7smJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/27CV//////////////////////////////////////////////////////////////////////+s0/z/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/2ev+v/4+/7/////////////////////////////////////////////////////////////////+/bz/8qMZP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8iIX5IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIiV+pyYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/Ki2P/+vTw////////////////////////////////////////////////////////////5/L+/12p+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/6PO/P/////////////////////////////////////////////////////////////////nyrn/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/x4hgSgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMiJX1nJiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/jwq3///////////////////////////////////////////////////////b6/v92t/v/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEST5VdFk+XvRZPl/0WT5f9Fk+X/R5XmagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEST5ANEkuSsRZPl70SS5JdDk+UWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAESS5RlFkuWaRZPk8ESS5KVEkuQBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////gAAAAD//////////////4AAAAAAAeAf//////////AAAAAAAAAAD/////////8AAAAAAAAAAAf///+AH//8AAAAAAAAAAAD///8AAP/4AAAAAAAAAAAA///8AAAf4AAAAAAAAAAAAH//8AAAD8AAAAAAAAAAAAB//+AAAAMAAAAAAAAAAAAAH/+AAAAAAAAAAAAAAAAAAA//AAAAAAAAAAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAA/4AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAB/AAAAAAAAAAAAAAAAAAAAPgAB+AAAAAAAAAAAAAAAAD4AB/4AAAAAAAAAAAAAAAAcAB//gAAAAAAAAAAAAAAAHAA//8AAAAAAAAAAAAAAABwAP//gAAAAAAAAAAAAAAAMAH//4AAAAAAAAAAAAAAADAB//+AAAAAAAAAAAAAAAAwAf//gAAAAAAAAAAAAAAAMAH//4AAAAAAAAAAAAAAABAB//+AAAAAAAAAAAAAAAAQAf//gAAAAAAAAAAAAAAAEAH//4AAAAAAAAAAAAAAABAB//+AAAAAAAAAAAAAAAAQAf//gAAAAAAAAAAAAAAAEAD//4AAAAAAAAAAAAAAABAA//+AAAAAAAAAAAAAAAAYAf//gAAAAAAAAAAAAAAAGAH//4AAAAAAAAAAAAAAABwD//+AAAAAAAAAAAAAAAAeB///gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAP////8AAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAP////+AAAAAAAAAAAAAAAH/////gAAAAAAAAAAAAAAB/////4AAAAAAAAAAAAAAAf/////AAAAAAAAAAAAAAAH/////wAAAAAAAAAAAAAAD/////8AAAAAAAAAAAAAAA//////gAAAAAAAAAAAAAAP/////4AAAAAAAAAAAAAAH/////+AAAAAAAAAAAAAAB//////wAAAAAAAAAAAAAAf/////8AAAAAAAAAAAAAAP//////gAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAB//////8AAAAAAAAAAAAAAf/////+AAAAAAAAAAAAAAP//////gAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAf//////AAAAAAAAAAAAAAH//////gAAAAAAAAAAAAAB//////4AAAAAAAAAAAAAAP/////+AAAAAAAAAAAAAAD//////AAAAAAAAAAAAAAA//////wAAAAAAAAAAAAAAP/////8AAAAAAAAAAAAAAB//////AAAAAAAAAAAAAAAf/////wAAAAAAAAAAAAAAH/////4AAAAAAAAAAAAAAB/////+AAAAAAAAAAAAAAAf/////gAAAAAAAAAAAAAAH/////4AAAAAAAAAAAAAAA/////+AAAAAAAAAAAAAAAP/////gAAAAAAAAAAAAAAD/////4AAAAAAAAAAAAAAA/////+AAAAAAAAAAAAAAAP/////gAAAAAAAAAAAAAAD/////4AAAAAAAAAAAAAAA/////+AAAAAAAAAAAAAAAP/////gAAAAAAAAAAAAAAD/////4AAAAAAAAAAAAAAB/////+AAAAAAAAAAAAAAAf/////gAAAAAAAAAAAAAAH/////8AAAAAAAAAAAAAAB//////AAAAAAAAAAAAAAAf/////wAAAAAAAAAAAAAAH/////8AAAAAAAAAAAAAAD//////AAAAAAAAAAAAAAA//////4AAAAAAAAAAAAAAP/////+AAAAAAAAAAAAAAD//////gAAAAAAAAAAAAAB//////8AAAAAAAAAAAAAAf//////AAAAAAAAAAAAAAH//////wAAAAAAAAAAAAAD//////+AAAAAAAAAAAAAA///////gAAAAAAAAAAAAAf//////8AAAAAAAAAAAAAH///////AAAAAAAAAAAAAD///////4AAAAAAAAAAAAA////////AAAAAAAAAAAAAf///////wAAAAAAAAAAAAP///////+AAAAAAAAAAAAD////////wAAAAAAAAAAAB////////8AAAAAAAAAAAA/////////gAAAAAAAAAAAP////////8AAAAAAAAAAAH/////////gAAAAAAAAAAD/////////8AAAAAAAAAAB//////////gAAAAAAAAAA//////////8AAAAAAAAAAf//////////gAAAAAAAAAP//////////4AAAAAAAAAH//////////+AAAAAAAAAD///////////gAAAAAAAAA///////////4AAAAAAAAAP//////////+AAAAAAAAAD///////////gAAAAAAAAA///////////4AAAAAAAAAP///////////AAAAAAAAAH///////////wAAAAAAAAB///////////8AAcAAAMAAf///////////AAP/AD/gAH///////////wAH////8AB///////////+AD/////gA////////////gB/////8AP///////////4A//////gD////////////A//////+B////////////wf//////wf///8=" -TRANS_ICO = "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACWAAAA8gAAAP4AAAD/AAAA8gAAAPIAAAD8AAAA/wAAAPIAAAC3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAB9AAAAjgAAAOwAAAD/AAAAYQAAACoAAAD/AAAA/wAAAEsAAAA2AAAA/wAAAPYAAAAAAAAAAAAAAAcAAACyAAAA/wAAAP8AAAD/AAAA/wAAAL4AAAAAAAAATAAAAE8AAAAAAAAAjAAAAP8AAADyAAAAAAAAAAAAAAB7AAAA/wAAAHsAAABFAAAA3gAAAP8AAAD/AAAACgAAAEQAAABvAAAAAAAAAP8AAAD/AAAA8gAAAAAAAAAAAAAAlwAAAP8AAAAjAAAAAAAAAMcAAAD/AAAA/wAAAHEAAAA9AAAAUwAAAEMAAAD/AAAA/wAAAPIAAACVAAAA6QAAAP8AAAD/AAAA/wAAAPQAAAD9AAAA/wAAAP8AAADyAAAAAAAAAAAAAADPAAAA/wAAAP8AAADyAAAA/wAAAL0AAACMAAAAZQAAAGIAAABqAAAA4AAAAP8AAAD/AAAA/wAAAFwAAAA7AAAA/wAAAP8AAAD/AAAA8wAAAPoAAABAAAAAsQAAAK8AAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD+AAAASQAAADQAAAC8AAAA/wAAAP4AAACwAAAAyQAAAOoAAAD+AAAA1QAAANYAAADQAAAA0QAAANIAAACWAAAA/wAAAFIAAAAAAAAAbwAAAP8AAAD/AAAANAAAAAAAAACDAAAA9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAArAAAAAAAAAP8AAAAdAAAAYwAAAP0AAAAAAAAAZgAAAPkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADtAAAAcAAAANYAAAD/AAAAmwAAALMAAAD/AAAAuQAAAIAAAADmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8wAAAF8AAABzAAAAaAAAAP0AAADgAAAAYQAAAF0AAACBAAAA7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAACLAAAAJwAAACYAAAB1AAAAZwAAACYAAAAtAAAAtwAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3AAAA/wAAAP8AAAD/AAAA7gAAAPMAAAD/AAAA/wAAAP8AAACTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/ABBTfwAbWXwAHJ54EhTRcBIUk/EAExFADA6XAgAZXIMAG1lIAByeWE/Qk9hv01TAD9JTgA/QUwzP1BBAD89Qw==" -ABOUT_ICO = "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMgAAAJEAAADOAAAA7QAAAO0AAADNAAAAkAAAADEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAkQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvAAAAP8AAAD/AAAA+wAAANoAAADZAAAA3AAAANcAAADjAAAA/wAAAP8AAAC5AAAAAAAAAAAAAAAAAAAAlwAAAP8AAAD/AAAA/wAAAMYAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAP8AAAD/AAAA/wAAAJIAAAAAAAAAKwAAAP8AAAD/AAAA/wAAAP8AAADqAAAAkwAAAB4AAAAAAAAARwAAAKMAAAD/AAAA/wAAAP8AAAD/AAAAJwAAAJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABVAAAAAAAAAKQAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAJcAAADaAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAATgAAAAAAAACMAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADXAAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD1AAAA4gAAAEMAAAAAAAAAjAAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8gAAAPUAAAD/AAAA/wAAAP8AAAD/AAAA4gAAABAAAAAAAAAAAAAAAIYAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPIAAADbAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADCAAAARgAAAAQAAACQAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADXAAAAmwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAC8AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAlwAAACwAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAM0AAAAeAAAAMQAAANQAAAD/AAAA/wAAAP8AAAD/AAAA/wAAACgAAAAAAAAAmAAAAP8AAAD/AAAA/wAAAP8AAACAAAAAAAAAAAAAAAB3AAAA/wAAAP8AAAD/AAAA/wAAAJQAAAAAAAAAAAAAAAAAAAC9AAAA/wAAAP8AAAD/AAAA5gAAAEEAAAA+AAAA4gAAAP8AAAD/AAAA/wAAALoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAJMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAAAAJMAAADPAAAA9gAAAPYAAADPAAAAkgAAADIAAAAAAAAAAAAAAAAAAAAA8A9BTeAHbWXAA3J5g+FTRQGAUk8AgExFAYA6XACAZXIBgG1lAYByeQAAQk8BgE1TgYFJTsADQUzgB1BB8A89Qw==" -CHECK_ICO = "AAABAAEAEBIAAAEAIADwBAAAFgAAACgAAAAQAAAAJAAAAAEAIAAAAAAAAAAAAGEPAABhDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsAAAA9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZwAAAH4AAACDAAAAlQAAABsAAABrAAAA7AAAAAwAAABcAAAAkQAAAH8AAACAAAAAggAAAH0AAAB5AAAAIwAAAPIAAAD/AAAA/wAAAOIAAABFAAAA0AAAAP8AAABrAAAAdgAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAFcAAAD/AAAA0gAAADAAAAAAAAAAeQAAAP8AAAD/AAAA8QAAACAAAAAcAAAARAAAAD4AAAAiAAAAjwAAAP8AAABRAAAA/wAAALoAAAAAAAAAHQAAAPkAAAD/AAAA/wAAAP8AAACaAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAD/AAAAUgAAAP8AAACxAAAAAAAAAJ8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAEoAAAAAAAAAAAAAAAAAAABnAAAA/wAAAFIAAADkAAAAGQAAAC8AAAD/AAAA/wAAAP8AAAD9AAAA/wAAAP8AAADNAAAAAQAAAAAAAAAAAAAAZwAAAP8AAABSAAAALQAAAAEAAADfAAAA/wAAAP8AAACyAAAAUwAAAP4AAAD/AAAA/wAAAHMAAAAAAAAAAAAAAGcAAAD/AAAAUgAAAF4AAAAcAAAAywAAAP8AAAD/AAAASAAAAAAAAACnAAAA/wAAAP8AAADwAAAAHAAAAAAAAABnAAAA/wAAAFIAAAD/AAAAiwAAAAAAAAB/AAAAmAAAAAAAAAAAAAAAJQAAAPcAAAD/AAAA/wAAAJ4AAAAAAAAAYQAAAP8AAABRAAAA/wAAAMcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBAAAA/wAAAP8AAAD/AAAAGAAAAFEAAAD/AAAAUAAAAP8AAAC/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAANgAAAD/AAAA/wAAAKwAAAAXAAAA6AAAAGwAAAD/AAAAvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUAAAA/wAAAP8AAAD/AAAAUAAAAAsAAAA2AAAA/wAAALUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAD/AAAA/wAAAOIAAAARAAAAAAAAAPoAAAD/AAAAvwAAAMEAAADEAAAAxAAAAMQAAADGAAAA3AAAAFkAAAAbAAAA9wAAAP8AAAD/AAAAjgAAAAAAAADSAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADgAAAAAAAAAHUAAAD/AAAA/wAAAP8AAABhAAAADQAAABAAAAAQAAAADwAAAA8AAAAPAAAADwAAAA8AAAANAAAAGwAAAAAAAAAGAAAA3gAAAP8AAADzAAAAXwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG8AAACuAAAAEAAAAAD//yAo//82Kd+HaWP//3Nv//8gVv//dWH//1N0//9pb///MS7//0Nv//9vbv//VG///3Nc//9TMf//Q0///1RP//9TPf//XFA=" -ALERT_ICO = "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAJAQAQCQEAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICEdDg4P/w4OD/8gICEdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgLxQUFc0UFBXNICAgLwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4eHiUaGhtZGBgZehgYGYMYGBl9GBgZfRgYGYMYGBl6GhobWR4eHiUAAAAAAAAAAAAAAAAAAAAAHBwcTBISE98PDxD/DQ0O/w0NDv8MDA3/DQ0O/w0NDv8MDA3/DQ0O/w0NDv8PDxD/EhIT3xwcHEwAAAAAAAAAABQUFa8ICAn/Dg4P/w8PEP8PDxD/Dw8Q/w8PEP8PDxD/Dw8Q/w8PEP8PDxD/Dg4P/wgICf8UFBWvAAAAAAAAAAAhISETERES4gwMDf8PDxD/Dw8Q/w8PEP8PDxD/Dw8Q/w8PEP8PDxD/Dw8Q/wwMDf8RERLiISEhEwAAAAAAAAAAAAAAACAgIBkQEBHmDQ0O/w8PEP8PDxD/Dw8Q/w8PEP8PDxD/Dw8Q/w0NDv8QEBHmICAgGQAAAAAAAAAAAAAAAAAAAAAAAAAAISEhIRAQEfUNDQ7/Dw8Q/w8PEP8PDxD/Dw8Q/w0NDv8QEBH1ISEhIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVFRa1DAwN/w8PEP8PDxD/Dw8Q/w8PEP8MDA3/FRUWtQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAExMUtQ0NDv8PDxD/Dw8Q/w8PEP8PDxD/DQ0O/xMTFLUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMTFLkNDQ7/Dw8Q/w8PEP8PDxD/Dw8Q/w0NDv8TExS5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUFBWsDAwN/w8PEP8PDxD/Dw8Q/w8PEP8MDA3/FBQVrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhobbAsLDP8PDxD/Dw8Q/w8PEP8PDxD/CwsM/xoaG2wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVFRbACgoM/w4OD/8ODg//CgoM/xUVFsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgYGXAPDxD/Dw8Q/xgYGXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhYXsBYWF7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/n9BTf5/bWXwD3J5gAFTRYABUk/AA0xF4Ac6XPAPZXLwD21l8A9yefAPQk/wD01T8A9JTvgfQUz8P1BB/n89Qw==" -OCR_ICO = "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVAAAA6QAAAOgAAABNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaAAAA/wAAAP8AAAD/AAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0AAAAAAAAAAAAAAAAAAABaAAAA/wAAAP8AAABTAAAAqgAAAP8AAAAAAAAAAAAAAAAAAABIAAAAwwAAAP8AAAD/AAAA/wAAALIAAAB4AAAA/wAAAP8AAABCAAAAAQAAAPoAAABrAAAAAAAAAAAAAACbAAAA/wAAAP8AAAC1AAAAkwAAALUAAAD/AAAA/wAAAP8AAAD+AAAAaQAAAP8AAAB6AAAAAAAAAAAAAACeAAAA/wAAAI4AAAAFAAAAAAAAAAAAAAAAAAAABQAAAIcAAAD/AAAA/wAAAP8AAABsAAAAAAAAAAAAAAA7AAAA/wAAAJMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiwAAAP8AAABzAAAAAAAAAAAAAAAAAAAA0wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+AAAAsQAAAAAAAAAAAAAAAAAAAP8AAACzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAswAAAP8AAAAEAAAAAAAAAAAAAAD/AAAAhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIUAAAD/AAAADgAAAAAAAAAAAAAA/wAAALMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyAAAA/wAAAAQAAAAAAAAAAAAAANMAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAANMAAAAAAAAAAAAAAAAAAAA7AAAA/wAAAJMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkwAAAP8AAAA7AAAAAAAAAAAAAAAAAAAAAAAAAJ4AAAD/AAAAjgAAAAUAAAAAAAAAAAAAAAAAAAAFAAAAjgAAAP8AAACeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmwAAAP8AAAD/AAAAtQAAAJMAAAC1AAAA/wAAAP8AAACbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAwwAAAP8AAAD/AAAA/wAAAMMAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//lBTf/wbWX/5HJ58A1TRcABUk+Pg0xFn8c6XD/nZXI/521lP+dyeT/nQk8/501Tn89JTo+PQUzAH1BB8H89Qw==" -PICK_ICO = "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUVFQAJCQkLPT09OF1dXVdvb29vgYGBiJCQkJaRkZGVhYWFhXJycm5hYWFXRkZGOQ4ODgwdHR0AAAAAAFJSUgAvLy8kkZGRq83NzfHg4OD96urq/9zc3P/Nzc3/zs7O/9vb2//r6+v/4uLi/dHR0fKVlZWuNTU1JmBgYAAAAAASlpaWsfDw8P///////v7+//7+/v/p6en/wMDA/8DAwP/o6Oj//v7+//7+/v//////8vLy/5qamrcFBQUWWlpaZNvb2/j//////Pz8//v7+//+/v7//v7+/8PDw//BwcH//v7+//7+/v/7+/v//Pz8///////e3t76YWFha4aGhqb19fX/6Ojo/3R0dP9XV1f/q6ur//n5+f+enp7/mpqa//r6+v+urq7/WFhY/3Fxcf/m5ub/9/f3/4yMjK6MjIyw+fn5/5SUlP8MDAz/MjIy/ykpKf+lpaX///////////+qqqr/KSkp/zMzM/8MDAz/jo6O//r6+v+SkpK4e3t7k/Hx8f90dHT/TU1N/2RkZP9wcHD/VVVV//b29v/4+Pj/WVlZ/25ubv9lZWX/UFBQ/25ubv/z8/P/gYGBmmNjY27n5+f9l5eX/05OTv99fX3/fHx8/2NjY//4+Pj/+vr6/2dnZ/96enr/fn5+/1BQUP+RkZH/6urq/mpqanY5OTk+zc3N7d7e3v8zMzP/KSkp/zIyMv/AwMD////////////ExMT/NDQ0/yoqKv8wMDD/2tra/9LS0vBBQUFFAAAADJmZmbL5+fn/wsLC/3t7e//AwMD//Pz8//z8/P/8/Pz//f39/8PDw/97e3v/v7+///r6+v+fn5+6AAAAEF5eXgAyMjJgtra2/P///////////v7+//z8/P/8/Pz//Pz8//z8/P/+/v7///////////+9vb39OTk5Z3l5eQAAAAAcAAAAvCUlJf+2trb//Pz8///////9/f3//f39//39/f/9/f3///////z8/P+7u7v/Kioq/wAAAMEAAAAgAAAAVwAAAPgAAAD/FhYW/3p6evTS0tLy6Ojo/+3t7f/s7Oz/5+fn/8/Pz/N6enrzFxcX/wAAAP8AAAD6AAAAXwAAADQAAADdAAAA/wAAAOgBAQFhSEhIO3BwcGh3d3d5c3NzeWlpaWlCQkI8AQEBXQAAAOYAAAD/AAAA4AAAADkAAAACAAAARgAAAIsAAABLAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAABIAAAAiwAAAEkAAAAC//8AAMADAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAAAAAAAAAAAAAAAAAB+AAAA==" -EXIT_ICO = "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAC6AAAA8gAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPIAAAC7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAP8AAAD/AAAAHQAAAAwAAAAOAAAADgAAAAwAAAAbAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAADXAAAA1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAMAAAA1wAAAOcAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAD/AAAA/wAAAAAAAAAMAAAA1wAAAP8AAADVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAA/wAAAP8AAAAPAAAA1wAAAP8AAADXAAAAGQAAAAwAAAAOAAAADgAAAA4AAAAPAAAAEQAAAAAAAAAAAAAAEAAAAP8AAAD/AAAA5AAAAP8AAAD/AAAA8AAAAPEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADXAAAAAAAAAAMAAAD/AAAA/wAAAOQAAAD/AAAA/wAAAPAAAADxAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA1wAAAAAAAAADAAAA/wAAAP8AAAAPAAAA1wAAAP8AAADXAAAAGQAAAAwAAAAOAAAADgAAAA4AAAAPAAAAEQAAAAAAAAAAAAAAEAAAAP8AAAD/AAAAAAAAAAwAAADXAAAA/wAAANUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAD/AAAA/wAAAAAAAAAAAAAADAAAANcAAADmAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAADXAAAA1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAA/wAAAP8AAAAdAAAADAAAAA4AAAAOAAAADAAAABsAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAC6AAAA8gAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPIAAAC7/ABBTfwAbWX8/HJ5/PxTRef8Uk/H/ExFh/w6XAAMZXIADG1lh/xyecf8Qk/n/E1T/PxJTvz8QUz8AFBB/AA9Qw==" diff --git a/memorytools/plugins/alert/alert.py b/memorytools/plugins/alert/alert.py index 2e36418..2ca7940 100644 --- a/memorytools/plugins/alert/alert.py +++ b/memorytools/plugins/alert/alert.py @@ -1,14 +1,14 @@ from time import time from easydict import EasyDict -from boxes import LabelBox -from setting import ALERT_MSG +from tools.boxes import LabelBox +from globals import TEXT, ICON from utils import isCheckIcon, isPickIcon from plugins import BasePlugin class Alert(BasePlugin): def __init__(self, root, config) -> None: - super(Alert, self).__init__("休息提醒", root, 'alert.ico', config) + super(Alert, self).__init__("休息提醒", root, ICON.alert, config) self.start_time = time() def getConfig(self) -> EasyDict: @@ -31,7 +31,7 @@ def alert(self): return True return False - def pauseAlert(self, sysTrayIcon): + def pauseAlert(self, s): self.config.is_alert = not self.config.is_alert if self.config.is_alert: self.start_time = time() @@ -40,24 +40,24 @@ def pauseAlert(self, sysTrayIcon): # LabelBox().show("虽然你关掉了休息提醒,但还是要注意身体!", "确定") self.root.refreshMenu() - def changeTime30(self, sysTrayIcon): + def changeTime30(self, s): self.config.alert_time = 30 self.root.refreshMenu() - def changeTime60(self, sysTrayIcon): + def changeTime60(self, s): self.config.alert_time = 60 self.root.refreshMenu() - def changeTime90(self, sysTrayIcon): + def changeTime90(self, s): self.config.alert_time = 90 self.root.refreshMenu() - def changeTime120(self, sysTrayIcon): + def changeTime120(self, s): self.config.alert_time = 120 self.root.refreshMenu() def start(self): if self.config.is_alert and self.alert(): - alert_message = "你已经连续工作 %d 分钟了!是时候休息一下了!\n%s" % (self.config.alert_time, ALERT_MSG) + alert_message = TEXT.alert % self.config.alert_time LabelBox('危险警报').show(alert_message, '等你想要继续工作了再点我') self.start_time = time() diff --git a/memorytools/plugins/base.py b/memorytools/plugins/base.py index 88249ca..8c81b2e 100644 --- a/memorytools/plugins/base.py +++ b/memorytools/plugins/base.py @@ -1,5 +1,4 @@ from easydict import EasyDict -from utils import getSrc class BasePlugin(object): @@ -9,11 +8,11 @@ def __init__(self, name: str, root, icon: str, config: EasyDict): self.icon = icon self.config = config[name] - def getConfig(self) -> EasyDict: + def getConfig(self) -> tuple: return self.name, self.config def createMenu(self) -> tuple: return () def initMenu(self) -> tuple: - return self.name, getSrc(self.icon), self.createMenu(), True + return self.name, self.icon, self.createMenu(), True diff --git a/memorytools/plugins/copytrans/copytrans.py b/memorytools/plugins/copytrans/copytrans.py index 35b723d..6d837b8 100644 --- a/memorytools/plugins/copytrans/copytrans.py +++ b/memorytools/plugins/copytrans/copytrans.py @@ -1,15 +1,16 @@ from easydict import EasyDict -from boxes import TextTextBox +from tools.boxes import TextTextBox from googletransx import Translator from utils import isCheckIcon, isPickIcon, judgeLanguage, pasteClip, copyClip from requests.exceptions import ConnectionError from plugins import BasePlugin +from globals import ICON class CopyTrans(BasePlugin): def __init__(self, root, config: EasyDict) -> None: - super(CopyTrans, self).__init__("复制翻译", root, "trans.ico", config) + super(CopyTrans, self).__init__("复制翻译", root, ICON.trans, config) self.last = '' # 记录上次的剪切板内容 self.translator = Translator(service_urls=['translate.google.cn']) # 获得翻译接口 diff --git a/memorytools/plugins/ocr/baiduOCR.py b/memorytools/plugins/ocr/baiduOCR.py index f5a4ea3..2f9f546 100644 --- a/memorytools/plugins/ocr/baiduOCR.py +++ b/memorytools/plugins/ocr/baiduOCR.py @@ -1,7 +1,7 @@ from aip import AipOcr from PIL import Image from utils import pil2bytes -from setting import BAIDU_ERROR_CODES +from globals import BAIDU_ERROR_CODES class BaiduOCR(object): diff --git a/memorytools/plugins/ocr/ocr.py b/memorytools/plugins/ocr/ocr.py index 56d0118..b7a3730 100644 --- a/memorytools/plugins/ocr/ocr.py +++ b/memorytools/plugins/ocr/ocr.py @@ -2,15 +2,15 @@ from . import BaiduOCR from . import LatexOCR from PIL import Image, ImageGrab, ImageDraw -from boxes import ImageTextBox -from setting import BAIDU_ACCOUNTS, XUEERSI_ACCOUNTS +from tools.boxes import ImageTextBox +from globals import BAIDU_ACCOUNTS, XUEERSI_ACCOUNTS, ICON from utils import isCheckIcon, isPickIcon, getRect, Color, copyClip from plugins import BasePlugin class OCR(BasePlugin): def __init__(self, root, config): - super(OCR, self).__init__("OCR识别", root, "ocr.ico", config) + super(OCR, self).__init__("OCR识别", root, ICON.ocr, config) self.textocr = BaiduOCR(BAIDU_ACCOUNTS) self.mathocr = LatexOCR(XUEERSI_ACCOUNTS) diff --git a/memorytools/plugins/ocr/xueersiOCR.py b/memorytools/plugins/ocr/xueersiOCR.py index d57d52c..95ee91b 100644 --- a/memorytools/plugins/ocr/xueersiOCR.py +++ b/memorytools/plugins/ocr/xueersiOCR.py @@ -6,7 +6,7 @@ from urllib.parse import quote from requests import post from utils import pil2bytes -from setting import ALPHADIG, XUEERSI_ERROR_CODES +from globals import ALPHADIG, XUEERSI_ERROR_CODES class XueersiOCR(object): diff --git a/memorytools/tools/__init__.py b/memorytools/tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/memorytools/boxes.py b/memorytools/tools/boxes.py similarity index 98% rename from memorytools/boxes.py rename to memorytools/tools/boxes.py index 88add5a..30a7a86 100644 --- a/memorytools/boxes.py +++ b/memorytools/tools/boxes.py @@ -8,7 +8,8 @@ from tkinter import Tk, END from tkinter.ttk import Label, Button, Frame from tkinter.scrolledtext import ScrolledText, Text -from utils import getTextLine, resizeImg, getSrc, copyClip +from utils import getTextLine, resizeImg, copyClip +from globals import ICON class BaseBox(Tk): @@ -23,7 +24,7 @@ def setWindow(self, title: str): self.screen_h = self.winfo_screenheight() self.title(title) self.resizable(False, False) - self.iconbitmap(getSrc('icon.ico')) + self.iconbitmap(ICON.icon) min_w = self.screen_w // 3 min_h = self.screen_h // 3 diff --git a/memorytools/tools/config.py b/memorytools/tools/config.py new file mode 100644 index 0000000..721e390 --- /dev/null +++ b/memorytools/tools/config.py @@ -0,0 +1,23 @@ +import json +from easydict import EasyDict +from globals import PATH + + +class Config(object): + def __init__(self, path=PATH.config): + self.path = path + + def readConfig(self) -> EasyDict: + """ + 读配置文件 + """ + config = self.path.read_text(encoding="utf-8") + return EasyDict(json.loads(config)) + + def writeConfig(self, data: dict): + """ + 写配置文件 + """ + config = json.dumps(data, indent=4, ensure_ascii=False) + self.path.write_text(config, encoding="utf-8") + diff --git a/memorytools/systray/__init__.py b/memorytools/tools/systray/__init__.py similarity index 100% rename from memorytools/systray/__init__.py rename to memorytools/tools/systray/__init__.py diff --git a/memorytools/systray/__version__.py b/memorytools/tools/systray/__version__.py similarity index 100% rename from memorytools/systray/__version__.py rename to memorytools/tools/systray/__version__.py diff --git a/memorytools/systray/traybar.py b/memorytools/tools/systray/traybar.py similarity index 100% rename from memorytools/systray/traybar.py rename to memorytools/tools/systray/traybar.py diff --git a/memorytools/systray/win32_adapter.py b/memorytools/tools/systray/win32_adapter.py similarity index 100% rename from memorytools/systray/win32_adapter.py rename to memorytools/tools/systray/win32_adapter.py diff --git a/memorytools/utils.py b/memorytools/utils.py index c7a950d..87b5986 100644 --- a/memorytools/utils.py +++ b/memorytools/utils.py @@ -7,7 +7,7 @@ from urllib.parse import quote from io import BytesIO from easydict import EasyDict -from setting import COLOR, SRC_PATH, ICONS, CONFIG, DEFAULT_CONFIG, NOTAS, PUNCTUATION_MAP +from globals import * class Color(object): @@ -40,17 +40,17 @@ def copyClip(text): def getTextLine(text: str): - '''返回所给的文本有几行''' + """返回所给的文本有几行""" return len(text.split('\n')) def getRect(x1: int, y1: int, x2: int, y2: int): - '''给定矩形框的左上角和右下角坐标,返回四个角的坐标''' + """给定矩形框的左上角和右下角坐标,返回四个角的坐标""" return [(x1, y1), (x2, y1), (x2, y2), (x1, y2)] def pil2bytes(im, img_type='png', b64=False): - '''将PIL.Image格式的图像转化为二进制数据''' + """将PIL.Image格式的图像转化为二进制数据""" bf = BytesIO() im.save(bf, img_type) img = bf.getvalue() @@ -84,32 +84,32 @@ def resizeImg(img, max_w: int, max_h: int): return img -def getSrc(pic: str): - """返回对应资源的完整路径""" - path = os.path.join(SRC_PATH, pic) - file = os.path.abspath(path) - - if not os.path.exists(SRC_PATH): - os.makedirs(SRC_PATH) - if not os.path.exists(file): - if pic in ICONS: - bs64toImg(ICONS[pic], file) - - return file +# def getSrc(pic: str): +# """返回对应资源的完整路径""" +# path = os.path.join(ICON_PATH, pic) +# file = os.path.abspath(path) +# +# if not os.path.exists(ICON_PATH): +# os.makedirs(ICON_PATH) +# if not os.path.exists(file): +# if pic in ICONS: +# bs64toImg(ICONS[pic], file) +# +# return file def isCheckIcon(check: bool): - '''是否选中(两种状态)''' - return getSrc('check.ico') if check else None + """是否选中(两种状态)""" + return ICON.check if check else None def isPickIcon(pick: bool): - '''是否被选中(多项中的一个)''' - return getSrc('pick.ico') if pick else None + """是否被选中(多项中的一个)""" + return ICON.pick if pick else None def img2base64(image: str): - '''将图像从文件中读取出来并转化为base64编码''' + """将图像从文件中读取出来并转化为base64编码""" with open(image, 'rb') as bin_data: image_data = bin_data.read() image_data_base64 = b64encode(image_data) @@ -117,38 +117,38 @@ def img2base64(image: str): return image_data_base64 -def readConfig(name=CONFIG) -> EasyDict: - """ - 读配置文件 - """ - if name == CONFIG and not os.path.exists(name): - resetConfig() - try: - with open(name, "r", encoding="utf-8") as f: - data = f.read() - return EasyDict(json.loads(data)) - except Exception as e: - print(e) - return DEFAULT_CONFIG - - -def writeConfig(data: dict, name=CONFIG): - """ - 写配置文件 - """ - try: - data = json.dumps(data, indent=4, ensure_ascii=False) - with open(name, "w", encoding="utf-8") as f: - f.write(data) - except Exception as e: - print(e) - - -def resetConfig(name=CONFIG): - """ - 重置配置文件 - """ - writeConfig(DEFAULT_CONFIG, name) +# def readConfig(config=PATH.config) -> EasyDict: +# """ +# 读配置文件 +# """ +# if config == PATH.config and not os.path.exists(name): +# resetConfig() +# try: +# with open(name, "r", encoding="utf-8") as f: +# data = f.read() +# return EasyDict(json.loads(data)) +# except Exception as e: +# print(e) +# return DEFAULT_CONFIG +# +# +# def writeConfig(data: dict, name=CONFIG): +# """ +# 写配置文件 +# """ +# try: +# data = json.dumps(data, indent=4, ensure_ascii=False) +# with open(name, "w", encoding="utf-8") as f: +# f.write(data) +# except Exception as e: +# print(e) +# +# +# def resetConfig(name=CONFIG): +# """ +# 重置配置文件 +# """ +# writeConfig(DEFAULT_CONFIG, name) def filterStr(sentence: str): From 3749b48132a00b2b9cb7a6ed51b710bc5174841e Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Sat, 10 Oct 2020 00:06:10 +0800 Subject: [PATCH 09/28] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E5=9B=BE=E6=A0=87?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- memorytools/globals.py | 36 +++++++++++++++------- memorytools/memorytools.py | 2 +- memorytools/plugins/__init__.py | 14 ++++----- memorytools/plugins/alert/alert.py | 2 +- memorytools/plugins/copytrans/copytrans.py | 2 +- memorytools/plugins/ocr/baiduOCR.py | 2 +- memorytools/plugins/ocr/ocr.py | 2 +- memorytools/plugins/ocr/xueersiOCR.py | 2 +- memorytools/tools/boxes.py | 2 +- memorytools/{ => tools}/utils.py | 2 +- 10 files changed, 40 insertions(+), 26 deletions(-) rename memorytools/{ => tools}/utils.py (99%) diff --git a/memorytools/globals.py b/memorytools/globals.py index 3919087..54a6378 100644 --- a/memorytools/globals.py +++ b/memorytools/globals.py @@ -1,7 +1,18 @@ from string import punctuation from easydict import EasyDict from pathlib import Path -# from src.src import * +from base64 import b64decode + +icon_bs64 = { + "icon.ico": "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8f9dr/X/Zrr8/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2m9/f9Wp/D/RpTl/5CNmP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/YpDH/0WT5f9Fk+X/RZPl4ESS5BoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEST5ZFFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/1+y9/9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9ysuf/xYlj/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/7aKcv9FkuT/RZPl/0WT5f9Fk+X/RZLkzESS5AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEk+RbRZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/Xa71/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///6ecmP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/do+y/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RJLklwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJLlGUWT5e9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9YqfL/a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///98tOH/yIlh/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/7KKdv9GkuP/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X+RJLkRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFkuWgRZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f5Ek+TaRJPlrUST5ZVFk+WSRJLkpUST5MxFk+T6RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/1Oj7/9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///66YjP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/bY+8/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+XbRJLkBgAAAAAAAAAAAAAAAAAAAAAAAAAARJLlJUWT5fxFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WS5epEk+V8RJPlHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEST4xBEk+RlRZPl2EWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/TZzq/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///+Dsdb/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/6qLfv9Fk+T/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Ek+VuAAAAAAAAAAAAAAAAAAAAAAAAAABEkuWQRZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Ek+SfRJLlDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEkuQERJPkeUWT5ftFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9GlOX/ar7+/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a77+/7SUgv/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/IiWD/ZJDF/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0ST5eNEk+UFAAAAAAAAAAAAAAAARJPkA0SS5elFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RJLkfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJLlS0WT5fhFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9itfn/a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///+Jrcr/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/6CMiP9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5VgAAAAAAAAAAAAAAABDk+U5RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0SS5KUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJPlYkWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/1ip8v9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///bL78/7qReP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/HiWH/W5HO/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RJLkugAAAAAAAAAAAAAAAEST5XdFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Ek+TzQ5HjFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJLluEWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/TJvq/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///+Qqb//yYlg/8mJYP/JiWD/yIlg/7mKcP+si3z/q4t9/7SKdP/EiWX/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/5eMkv9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X7RZPkEwAAAAAAAAAARJLkpUWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0ST5ZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEkuQ4RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/Zbj7/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///brz4/7+OcP/JiWD/wYln/3+Oqf9Qktn/RZPl/0WT5f9Fk+X/RZPl/0WS5P9ZkdD/eo6v/6OLhv/GiWL/yYlg/8mJYP/FiWT/VJHV/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+VaAAAAAAAAAABEkuTGRZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RJPkVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAESS5SZFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Wp/H/a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///+XpbT/yYlg/8eJYf9gkcn/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/1OR1v+NjZv/xIlk/42Nm/9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0ST5ZoAAAAAAAAAAEWS5dtFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9EkuQrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJPkWEWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0iW5/9pvf7/a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///cbvz/8OM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+v9Wpvr/Vqb6/1am+v9Wpvr/os78//3+/v/////////////////////////////////////////////////////////////////RnHn/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/IiF8sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADJiGCPyYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/ny7n/////////////////////////////////////////////////9ff6/9vk7f/v8/f//////+Tx/v9jrPr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9LluX/MW+w/yJZk/8iWZL/IlmS/yJZkv8iWZL/IlmS/yJZkv8iWZL/IlmS/yJZkv8jW5X/OnzC/1Sj9/9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/6XQ/P////////////z9/v/f5+//5Ovy//7+/v///////////////////////////////////////////9Off//JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8iJXzQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMmJYJPJiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/+jMu///////////////////////////////////////9/n7/36dv/8oXJT/IliS/yNZkv9ojbT/6/D1/9Dm/f9Wpvr/Vqb6/1am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/v9HdKT/IliS/yJYkv8iWJL/IliS/yJYkv8iWJL/bpG3////////////////////////////9enh/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yIhf6wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMiIXy3JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8qMZf/+/fz/////////////////////////////////iKXE/yJYkv8iWJL/IliS/yJYkv8iWJL/Y4my//3+/v//////5PH+/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/mcn8/////////////////8nW5P8oXJX/IliS/yJYkv8iWJL/IliS/zVmm//j6vH////////////////////////////s1cf/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiF/JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAx4dgCcmJX/3JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg//Xq4v/////////////////////////////////+/v7/qL3U/0h1pf8nXJT/Pm2g/5Ksyf/5+/z////////////m8v7/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v+ayvz//////////////////////9Lc6P9fhrD/LF+W/zBjmf9vkrj/4+rx/////////////////////////////////+G+p//JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8iIX6YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyYlf3MmJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/6c++/////////////////////////////////////////////////////////////////////////////////9rr/f9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/47D+///////////////////////////////////////////////////////////////////////////////////////1KKD/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yIlfegAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIiF+ryYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/ar5T/////////////////////////////////////////////////////////////////////////////////vdz9/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/cbT6//////////////////////////////////////////////////////////////////////////////////v39P/JimL/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/IiV9LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMiIX3LJiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8yQaf/9/Pv///////////////////////////////////////////////////////////////////////////+Rxfv/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/7fX+////////////////////////////////////////////////////////////////////////////7NbI/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/siIXxMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyIhfNsmJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/+7bz///////////////////////////////////////////////////////////////////////9fn+/12q+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v+x1vz////////////////////////////////////////////////////////////////////////////ar5P/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/IiGDWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIiV4DyYhg7smJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/27CV//////////////////////////////////////////////////////////////////////+s0/z/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/2ev+v/4+/7/////////////////////////////////////////////////////////////////+/bz/8qMZP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8iIX5IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIiV+pyYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/Ki2P/+vTw////////////////////////////////////////////////////////////5/L+/12p+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/6PO/P/////////////////////////////////////////////////////////////////nyrn/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/x4hgSgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMiJX1nJiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/jwq3///////////////////////////////////////////////////////b6/v92t/v/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEST5VdFk+XvRZPl/0WT5f9Fk+X/R5XmagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEST5ANEkuSsRZPl70SS5JdDk+UWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAESS5RlFkuWaRZPk8ESS5KVEkuQBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////gAAAAD//////////////4AAAAAAAeAf//////////AAAAAAAAAAD/////////8AAAAAAAAAAAf///+AH//8AAAAAAAAAAAD///8AAP/4AAAAAAAAAAAA///8AAAf4AAAAAAAAAAAAH//8AAAD8AAAAAAAAAAAAB//+AAAAMAAAAAAAAAAAAAH/+AAAAAAAAAAAAAAAAAAA//AAAAAAAAAAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAA/4AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAB/AAAAAAAAAAAAAAAAAAAAPgAB+AAAAAAAAAAAAAAAAD4AB/4AAAAAAAAAAAAAAAAcAB//gAAAAAAAAAAAAAAAHAA//8AAAAAAAAAAAAAAABwAP//gAAAAAAAAAAAAAAAMAH//4AAAAAAAAAAAAAAADAB//+AAAAAAAAAAAAAAAAwAf//gAAAAAAAAAAAAAAAMAH//4AAAAAAAAAAAAAAABAB//+AAAAAAAAAAAAAAAAQAf//gAAAAAAAAAAAAAAAEAH//4AAAAAAAAAAAAAAABAB//+AAAAAAAAAAAAAAAAQAf//gAAAAAAAAAAAAAAAEAD//4AAAAAAAAAAAAAAABAA//+AAAAAAAAAAAAAAAAYAf//gAAAAAAAAAAAAAAAGAH//4AAAAAAAAAAAAAAABwD//+AAAAAAAAAAAAAAAAeB///gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAP////8AAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAP////+AAAAAAAAAAAAAAAH/////gAAAAAAAAAAAAAAB/////4AAAAAAAAAAAAAAAf/////AAAAAAAAAAAAAAAH/////wAAAAAAAAAAAAAAD/////8AAAAAAAAAAAAAAA//////gAAAAAAAAAAAAAAP/////4AAAAAAAAAAAAAAH/////+AAAAAAAAAAAAAAB//////wAAAAAAAAAAAAAAf/////8AAAAAAAAAAAAAAP//////gAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAB//////8AAAAAAAAAAAAAAf/////+AAAAAAAAAAAAAAP//////gAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAf//////AAAAAAAAAAAAAAH//////gAAAAAAAAAAAAAB//////4AAAAAAAAAAAAAAP/////+AAAAAAAAAAAAAAD//////AAAAAAAAAAAAAAA//////wAAAAAAAAAAAAAAP/////8AAAAAAAAAAAAAAB//////AAAAAAAAAAAAAAAf/////wAAAAAAAAAAAAAAH/////4AAAAAAAAAAAAAAB/////+AAAAAAAAAAAAAAAf/////gAAAAAAAAAAAAAAH/////4AAAAAAAAAAAAAAA/////+AAAAAAAAAAAAAAAP/////gAAAAAAAAAAAAAAD/////4AAAAAAAAAAAAAAA/////+AAAAAAAAAAAAAAAP/////gAAAAAAAAAAAAAAD/////4AAAAAAAAAAAAAAA/////+AAAAAAAAAAAAAAAP/////gAAAAAAAAAAAAAAD/////4AAAAAAAAAAAAAAB/////+AAAAAAAAAAAAAAAf/////gAAAAAAAAAAAAAAH/////8AAAAAAAAAAAAAAB//////AAAAAAAAAAAAAAAf/////wAAAAAAAAAAAAAAH/////8AAAAAAAAAAAAAAD//////AAAAAAAAAAAAAAA//////4AAAAAAAAAAAAAAP/////+AAAAAAAAAAAAAAD//////gAAAAAAAAAAAAAB//////8AAAAAAAAAAAAAAf//////AAAAAAAAAAAAAAH//////wAAAAAAAAAAAAAD//////+AAAAAAAAAAAAAA///////gAAAAAAAAAAAAAf//////8AAAAAAAAAAAAAH///////AAAAAAAAAAAAAD///////4AAAAAAAAAAAAA////////AAAAAAAAAAAAAf///////wAAAAAAAAAAAAP///////+AAAAAAAAAAAAD////////wAAAAAAAAAAAB////////8AAAAAAAAAAAA/////////gAAAAAAAAAAAP////////8AAAAAAAAAAAH/////////gAAAAAAAAAAD/////////8AAAAAAAAAAB//////////gAAAAAAAAAA//////////8AAAAAAAAAAf//////////gAAAAAAAAAP//////////4AAAAAAAAAH//////////+AAAAAAAAAD///////////gAAAAAAAAA///////////4AAAAAAAAAP//////////+AAAAAAAAAD///////////gAAAAAAAAA///////////4AAAAAAAAAP///////////AAAAAAAAAH///////////wAAAAAAAAB///////////8AAcAAAMAAf///////////AAP/AD/gAH///////////wAH////8AB///////////+AD/////gA////////////gB/////8AP///////////4A//////gD////////////A//////+B////////////wf//////wf///8=", + "trans.ico": "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACWAAAA8gAAAP4AAAD/AAAA8gAAAPIAAAD8AAAA/wAAAPIAAAC3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAB9AAAAjgAAAOwAAAD/AAAAYQAAACoAAAD/AAAA/wAAAEsAAAA2AAAA/wAAAPYAAAAAAAAAAAAAAAcAAACyAAAA/wAAAP8AAAD/AAAA/wAAAL4AAAAAAAAATAAAAE8AAAAAAAAAjAAAAP8AAADyAAAAAAAAAAAAAAB7AAAA/wAAAHsAAABFAAAA3gAAAP8AAAD/AAAACgAAAEQAAABvAAAAAAAAAP8AAAD/AAAA8gAAAAAAAAAAAAAAlwAAAP8AAAAjAAAAAAAAAMcAAAD/AAAA/wAAAHEAAAA9AAAAUwAAAEMAAAD/AAAA/wAAAPIAAACVAAAA6QAAAP8AAAD/AAAA/wAAAPQAAAD9AAAA/wAAAP8AAADyAAAAAAAAAAAAAADPAAAA/wAAAP8AAADyAAAA/wAAAL0AAACMAAAAZQAAAGIAAABqAAAA4AAAAP8AAAD/AAAA/wAAAFwAAAA7AAAA/wAAAP8AAAD/AAAA8wAAAPoAAABAAAAAsQAAAK8AAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD+AAAASQAAADQAAAC8AAAA/wAAAP4AAACwAAAAyQAAAOoAAAD+AAAA1QAAANYAAADQAAAA0QAAANIAAACWAAAA/wAAAFIAAAAAAAAAbwAAAP8AAAD/AAAANAAAAAAAAACDAAAA9wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAArAAAAAAAAAP8AAAAdAAAAYwAAAP0AAAAAAAAAZgAAAPkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADtAAAAcAAAANYAAAD/AAAAmwAAALMAAAD/AAAAuQAAAIAAAADmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8wAAAF8AAABzAAAAaAAAAP0AAADgAAAAYQAAAF0AAACBAAAA7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAACLAAAAJwAAACYAAAB1AAAAZwAAACYAAAAtAAAAtwAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC3AAAA/wAAAP8AAAD/AAAA7gAAAPMAAAD/AAAA/wAAAP8AAACTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/ABBTfwAbWXwAHJ54EhTRcBIUk/EAExFADA6XAgAZXIMAG1lIAByeWE/Qk9hv01TAD9JTgA/QUwzP1BBAD89Qw==", + "about.ico": "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMgAAAJEAAADOAAAA7QAAAO0AAADNAAAAkAAAADEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAkQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvAAAAP8AAAD/AAAA+wAAANoAAADZAAAA3AAAANcAAADjAAAA/wAAAP8AAAC5AAAAAAAAAAAAAAAAAAAAlwAAAP8AAAD/AAAA/wAAAMYAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAP8AAAD/AAAA/wAAAJIAAAAAAAAAKwAAAP8AAAD/AAAA/wAAAP8AAADqAAAAkwAAAB4AAAAAAAAARwAAAKMAAAD/AAAA/wAAAP8AAAD/AAAAJwAAAJsAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAABVAAAAAAAAAKQAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAJcAAADaAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAATgAAAAAAAACMAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADXAAAA9QAAAP8AAAD/AAAA/wAAAP8AAAD1AAAA4gAAAEMAAAAAAAAAjAAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8gAAAPUAAAD/AAAA/wAAAP8AAAD/AAAA4gAAABAAAAAAAAAAAAAAAIYAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPIAAADbAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADCAAAARgAAAAQAAACQAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADXAAAAmwAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPsAAAC8AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAlwAAACwAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAM0AAAAeAAAAMQAAANQAAAD/AAAA/wAAAP8AAAD/AAAA/wAAACgAAAAAAAAAmAAAAP8AAAD/AAAA/wAAAP8AAACAAAAAAAAAAAAAAAB3AAAA/wAAAP8AAAD/AAAA/wAAAJQAAAAAAAAAAAAAAAAAAAC9AAAA/wAAAP8AAAD/AAAA5gAAAEEAAAA+AAAA4gAAAP8AAAD/AAAA/wAAALoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAJMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAAAAJMAAADPAAAA9gAAAPYAAADPAAAAkgAAADIAAAAAAAAAAAAAAAAAAAAA8A9BTeAHbWXAA3J5g+FTRQGAUk8AgExFAYA6XACAZXIBgG1lAYByeQAAQk8BgE1TgYFJTsADQUzgB1BB8A89Qw==", + "check.ico": "AAABAAEAEBIAAAEAIADwBAAAFgAAACgAAAAQAAAAJAAAAAEAIAAAAAAAAAAAAGEPAABhDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsAAAA9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZwAAAH4AAACDAAAAlQAAABsAAABrAAAA7AAAAAwAAABcAAAAkQAAAH8AAACAAAAAggAAAH0AAAB5AAAAIwAAAPIAAAD/AAAA/wAAAOIAAABFAAAA0AAAAP8AAABrAAAAdgAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAFcAAAD/AAAA0gAAADAAAAAAAAAAeQAAAP8AAAD/AAAA8QAAACAAAAAcAAAARAAAAD4AAAAiAAAAjwAAAP8AAABRAAAA/wAAALoAAAAAAAAAHQAAAPkAAAD/AAAA/wAAAP8AAACaAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAD/AAAAUgAAAP8AAACxAAAAAAAAAJ8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAEoAAAAAAAAAAAAAAAAAAABnAAAA/wAAAFIAAADkAAAAGQAAAC8AAAD/AAAA/wAAAP8AAAD9AAAA/wAAAP8AAADNAAAAAQAAAAAAAAAAAAAAZwAAAP8AAABSAAAALQAAAAEAAADfAAAA/wAAAP8AAACyAAAAUwAAAP4AAAD/AAAA/wAAAHMAAAAAAAAAAAAAAGcAAAD/AAAAUgAAAF4AAAAcAAAAywAAAP8AAAD/AAAASAAAAAAAAACnAAAA/wAAAP8AAADwAAAAHAAAAAAAAABnAAAA/wAAAFIAAAD/AAAAiwAAAAAAAAB/AAAAmAAAAAAAAAAAAAAAJQAAAPcAAAD/AAAA/wAAAJ4AAAAAAAAAYQAAAP8AAABRAAAA/wAAAMcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBAAAA/wAAAP8AAAD/AAAAGAAAAFEAAAD/AAAAUAAAAP8AAAC/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAANgAAAD/AAAA/wAAAKwAAAAXAAAA6AAAAGwAAAD/AAAAvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUAAAA/wAAAP8AAAD/AAAAUAAAAAsAAAA2AAAA/wAAALUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAD/AAAA/wAAAOIAAAARAAAAAAAAAPoAAAD/AAAAvwAAAMEAAADEAAAAxAAAAMQAAADGAAAA3AAAAFkAAAAbAAAA9wAAAP8AAAD/AAAAjgAAAAAAAADSAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADgAAAAAAAAAHUAAAD/AAAA/wAAAP8AAABhAAAADQAAABAAAAAQAAAADwAAAA8AAAAPAAAADwAAAA8AAAANAAAAGwAAAAAAAAAGAAAA3gAAAP8AAADzAAAAXwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG8AAACuAAAAEAAAAAD//yAo//82Kd+HaWP//3Nv//8gVv//dWH//1N0//9pb///MS7//0Nv//9vbv//VG///3Nc//9TMf//Q0///1RP//9TPf//XFA=", + "alert.ico": "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAJAQAQCQEAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICEdDg4P/w4OD/8gICEdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgLxQUFc0UFBXNICAgLwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4eHiUaGhtZGBgZehgYGYMYGBl9GBgZfRgYGYMYGBl6GhobWR4eHiUAAAAAAAAAAAAAAAAAAAAAHBwcTBISE98PDxD/DQ0O/w0NDv8MDA3/DQ0O/w0NDv8MDA3/DQ0O/w0NDv8PDxD/EhIT3xwcHEwAAAAAAAAAABQUFa8ICAn/Dg4P/w8PEP8PDxD/Dw8Q/w8PEP8PDxD/Dw8Q/w8PEP8PDxD/Dg4P/wgICf8UFBWvAAAAAAAAAAAhISETERES4gwMDf8PDxD/Dw8Q/w8PEP8PDxD/Dw8Q/w8PEP8PDxD/Dw8Q/wwMDf8RERLiISEhEwAAAAAAAAAAAAAAACAgIBkQEBHmDQ0O/w8PEP8PDxD/Dw8Q/w8PEP8PDxD/Dw8Q/w0NDv8QEBHmICAgGQAAAAAAAAAAAAAAAAAAAAAAAAAAISEhIRAQEfUNDQ7/Dw8Q/w8PEP8PDxD/Dw8Q/w0NDv8QEBH1ISEhIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVFRa1DAwN/w8PEP8PDxD/Dw8Q/w8PEP8MDA3/FRUWtQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAExMUtQ0NDv8PDxD/Dw8Q/w8PEP8PDxD/DQ0O/xMTFLUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMTFLkNDQ7/Dw8Q/w8PEP8PDxD/Dw8Q/w0NDv8TExS5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUFBWsDAwN/w8PEP8PDxD/Dw8Q/w8PEP8MDA3/FBQVrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhobbAsLDP8PDxD/Dw8Q/w8PEP8PDxD/CwsM/xoaG2wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVFRbACgoM/w4OD/8ODg//CgoM/xUVFsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgYGXAPDxD/Dw8Q/xgYGXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhYXsBYWF7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/n9BTf5/bWXwD3J5gAFTRYABUk/AA0xF4Ac6XPAPZXLwD21l8A9yefAPQk/wD01T8A9JTvgfQUz8P1BB/n89Qw==", + "ocr.ico": "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVAAAA6QAAAOgAAABNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaAAAA/wAAAP8AAAD/AAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0AAAAAAAAAAAAAAAAAAABaAAAA/wAAAP8AAABTAAAAqgAAAP8AAAAAAAAAAAAAAAAAAABIAAAAwwAAAP8AAAD/AAAA/wAAALIAAAB4AAAA/wAAAP8AAABCAAAAAQAAAPoAAABrAAAAAAAAAAAAAACbAAAA/wAAAP8AAAC1AAAAkwAAALUAAAD/AAAA/wAAAP8AAAD+AAAAaQAAAP8AAAB6AAAAAAAAAAAAAACeAAAA/wAAAI4AAAAFAAAAAAAAAAAAAAAAAAAABQAAAIcAAAD/AAAA/wAAAP8AAABsAAAAAAAAAAAAAAA7AAAA/wAAAJMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiwAAAP8AAABzAAAAAAAAAAAAAAAAAAAA0wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD+AAAAsQAAAAAAAAAAAAAAAAAAAP8AAACzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAswAAAP8AAAAEAAAAAAAAAAAAAAD/AAAAhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIUAAAD/AAAADgAAAAAAAAAAAAAA/wAAALMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyAAAA/wAAAAQAAAAAAAAAAAAAANMAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAANMAAAAAAAAAAAAAAAAAAAA7AAAA/wAAAJMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkwAAAP8AAAA7AAAAAAAAAAAAAAAAAAAAAAAAAJ4AAAD/AAAAjgAAAAUAAAAAAAAAAAAAAAAAAAAFAAAAjgAAAP8AAACeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmwAAAP8AAAD/AAAAtQAAAJMAAAC1AAAA/wAAAP8AAACbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAwwAAAP8AAAD/AAAA/wAAAMMAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//lBTf/wbWX/5HJ58A1TRcABUk+Pg0xFn8c6XD/nZXI/521lP+dyeT/nQk8/501Tn89JTo+PQUzAH1BB8H89Qw==", + "pick.ico": "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUVFQAJCQkLPT09OF1dXVdvb29vgYGBiJCQkJaRkZGVhYWFhXJycm5hYWFXRkZGOQ4ODgwdHR0AAAAAAFJSUgAvLy8kkZGRq83NzfHg4OD96urq/9zc3P/Nzc3/zs7O/9vb2//r6+v/4uLi/dHR0fKVlZWuNTU1JmBgYAAAAAASlpaWsfDw8P///////v7+//7+/v/p6en/wMDA/8DAwP/o6Oj//v7+//7+/v//////8vLy/5qamrcFBQUWWlpaZNvb2/j//////Pz8//v7+//+/v7//v7+/8PDw//BwcH//v7+//7+/v/7+/v//Pz8///////e3t76YWFha4aGhqb19fX/6Ojo/3R0dP9XV1f/q6ur//n5+f+enp7/mpqa//r6+v+urq7/WFhY/3Fxcf/m5ub/9/f3/4yMjK6MjIyw+fn5/5SUlP8MDAz/MjIy/ykpKf+lpaX///////////+qqqr/KSkp/zMzM/8MDAz/jo6O//r6+v+SkpK4e3t7k/Hx8f90dHT/TU1N/2RkZP9wcHD/VVVV//b29v/4+Pj/WVlZ/25ubv9lZWX/UFBQ/25ubv/z8/P/gYGBmmNjY27n5+f9l5eX/05OTv99fX3/fHx8/2NjY//4+Pj/+vr6/2dnZ/96enr/fn5+/1BQUP+RkZH/6urq/mpqanY5OTk+zc3N7d7e3v8zMzP/KSkp/zIyMv/AwMD////////////ExMT/NDQ0/yoqKv8wMDD/2tra/9LS0vBBQUFFAAAADJmZmbL5+fn/wsLC/3t7e//AwMD//Pz8//z8/P/8/Pz//f39/8PDw/97e3v/v7+///r6+v+fn5+6AAAAEF5eXgAyMjJgtra2/P///////////v7+//z8/P/8/Pz//Pz8//z8/P/+/v7///////////+9vb39OTk5Z3l5eQAAAAAcAAAAvCUlJf+2trb//Pz8///////9/f3//f39//39/f/9/f3///////z8/P+7u7v/Kioq/wAAAMEAAAAgAAAAVwAAAPgAAAD/FhYW/3p6evTS0tLy6Ojo/+3t7f/s7Oz/5+fn/8/Pz/N6enrzFxcX/wAAAP8AAAD6AAAAXwAAADQAAADdAAAA/wAAAOgBAQFhSEhIO3BwcGh3d3d5c3NzeWlpaWlCQkI8AQEBXQAAAOYAAAD/AAAA4AAAADkAAAACAAAARgAAAIsAAABLAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAABIAAAAiwAAAEkAAAAC//8AAMADAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAAAAAAAAAAAAAAAAAAB+AAAA==", + "exit.ico": "AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAC6AAAA8gAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPIAAAC7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAP8AAAD/AAAAHQAAAAwAAAAOAAAADgAAAAwAAAAbAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAADXAAAA1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAMAAAA1wAAAOcAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAD/AAAA/wAAAAAAAAAMAAAA1wAAAP8AAADVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAA/wAAAP8AAAAPAAAA1wAAAP8AAADXAAAAGQAAAAwAAAAOAAAADgAAAA4AAAAPAAAAEQAAAAAAAAAAAAAAEAAAAP8AAAD/AAAA5AAAAP8AAAD/AAAA8AAAAPEAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADXAAAAAAAAAAMAAAD/AAAA/wAAAOQAAAD/AAAA/wAAAPAAAADxAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA1wAAAAAAAAADAAAA/wAAAP8AAAAPAAAA1wAAAP8AAADXAAAAGQAAAAwAAAAOAAAADgAAAA4AAAAPAAAAEQAAAAAAAAAAAAAAEAAAAP8AAAD/AAAAAAAAAAwAAADXAAAA/wAAANUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAD/AAAA/wAAAAAAAAAAAAAADAAAANcAAADmAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAADXAAAA1QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAA/wAAAP8AAAAdAAAADAAAAA4AAAAOAAAADAAAABsAAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAC6AAAA8gAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPIAAAC7/ABBTfwAbWX8/HJ5/PxTRef8Uk/H/ExFh/w6XAAMZXIADG1lh/xyecf8Qk/n/E1T/PxJTvz8QUz8AFBB/AA9Qw==", +} class PATH: @@ -16,20 +27,23 @@ class TEXT: alert = '你已经连续工作 %d 分钟了!是时候休息一下了!\ntip: 连续在电脑前工作太久容易脱发,得颈椎病,猝死。' -ICON = EasyDict() -for ico in PATH.icon.glob("*.ico"): - ICON[ico.stem] = str(ico) +def get_icon(): + if not PATH.icon.exists(): + PATH.icon.mkdir(parents=True, exist_ok=True) + + for name, ico in icon_bs64.items(): + name = PATH.icon / name + if not name.exists(): + name.write_bytes(b64decode(ico)) + icons = EasyDict() + for ico in PATH.icon.glob("*.ico"): + icons[ico.stem] = str(ico) -# ABOUT_IMG = 'README.png' -# -# ICONS = { -# 'icon.ico': ICON_ICO, 'trans.ico': TRANS_ICO, 'ocr.ico': OCR_ICO, -# 'alert.ico': ALERT_ICO, 'exit.ico': EXIT_ICO, 'about.ico': ABOUT_ICO, -# 'check.ico': CHECK_ICO, 'pick.ico': PICK_ICO -# } + return icons +ICON = get_icon() ALPHADIG = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' COLOR = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 0, 255), (0, 255, 255)] diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index 9085cf6..b43d43b 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -1,5 +1,6 @@ import webbrowser from PIL import Image +from globals import TEXT, ICON from time import sleep from plugins.ocr import OCR from plugins.alert import Alert @@ -7,7 +8,6 @@ from tools.systray import SysTrayIcon from tools.config import Config from tools.boxes import ImageBox -from globals import TEXT, ICON class MemoryTool(object): diff --git a/memorytools/plugins/__init__.py b/memorytools/plugins/__init__.py index 81a9eeb..8d39251 100644 --- a/memorytools/plugins/__init__.py +++ b/memorytools/plugins/__init__.py @@ -2,14 +2,14 @@ from .base import BasePlugin -plugin_path = Path() / "plugins" +# plugin_path = Path() / "plugins" +# +# all_plugins = [] +# for d in plugin_path.iterdir(): +# if d.is_dir() and d.name != "__pycache__": +# all_plugins.append(__import__("plugins."+d.name)) -all_plugins = [] -for d in plugin_path.iterdir(): - if d.is_dir() and d.name != "__pycache__": - all_plugins.append(__import__("plugins."+d.name)) - -print(all_plugins) +# print(all_plugins) diff --git a/memorytools/plugins/alert/alert.py b/memorytools/plugins/alert/alert.py index 2ca7940..1ad321e 100644 --- a/memorytools/plugins/alert/alert.py +++ b/memorytools/plugins/alert/alert.py @@ -2,7 +2,7 @@ from easydict import EasyDict from tools.boxes import LabelBox from globals import TEXT, ICON -from utils import isCheckIcon, isPickIcon +from tools.utils import isCheckIcon, isPickIcon from plugins import BasePlugin diff --git a/memorytools/plugins/copytrans/copytrans.py b/memorytools/plugins/copytrans/copytrans.py index 6d837b8..46aba9e 100644 --- a/memorytools/plugins/copytrans/copytrans.py +++ b/memorytools/plugins/copytrans/copytrans.py @@ -2,7 +2,7 @@ from tools.boxes import TextTextBox from googletransx import Translator -from utils import isCheckIcon, isPickIcon, judgeLanguage, pasteClip, copyClip +from tools.utils import isCheckIcon, isPickIcon, judgeLanguage, pasteClip from requests.exceptions import ConnectionError from plugins import BasePlugin from globals import ICON diff --git a/memorytools/plugins/ocr/baiduOCR.py b/memorytools/plugins/ocr/baiduOCR.py index 2f9f546..248f0d3 100644 --- a/memorytools/plugins/ocr/baiduOCR.py +++ b/memorytools/plugins/ocr/baiduOCR.py @@ -1,6 +1,6 @@ from aip import AipOcr from PIL import Image -from utils import pil2bytes +from tools.utils import pil2bytes from globals import BAIDU_ERROR_CODES diff --git a/memorytools/plugins/ocr/ocr.py b/memorytools/plugins/ocr/ocr.py index b7a3730..0a5116e 100644 --- a/memorytools/plugins/ocr/ocr.py +++ b/memorytools/plugins/ocr/ocr.py @@ -4,7 +4,7 @@ from PIL import Image, ImageGrab, ImageDraw from tools.boxes import ImageTextBox from globals import BAIDU_ACCOUNTS, XUEERSI_ACCOUNTS, ICON -from utils import isCheckIcon, isPickIcon, getRect, Color, copyClip +from tools.utils import isCheckIcon, isPickIcon, getRect, Color, copyClip from plugins import BasePlugin diff --git a/memorytools/plugins/ocr/xueersiOCR.py b/memorytools/plugins/ocr/xueersiOCR.py index 95ee91b..6ac0555 100644 --- a/memorytools/plugins/ocr/xueersiOCR.py +++ b/memorytools/plugins/ocr/xueersiOCR.py @@ -5,7 +5,7 @@ from base64 import b64encode from urllib.parse import quote from requests import post -from utils import pil2bytes +from tools.utils import pil2bytes from globals import ALPHADIG, XUEERSI_ERROR_CODES diff --git a/memorytools/tools/boxes.py b/memorytools/tools/boxes.py index 30a7a86..12e5a5f 100644 --- a/memorytools/tools/boxes.py +++ b/memorytools/tools/boxes.py @@ -8,7 +8,7 @@ from tkinter import Tk, END from tkinter.ttk import Label, Button, Frame from tkinter.scrolledtext import ScrolledText, Text -from utils import getTextLine, resizeImg, copyClip +from tools.utils import getTextLine, resizeImg, copyClip from globals import ICON diff --git a/memorytools/utils.py b/memorytools/tools/utils.py similarity index 99% rename from memorytools/utils.py rename to memorytools/tools/utils.py index 87b5986..60302fc 100644 --- a/memorytools/utils.py +++ b/memorytools/tools/utils.py @@ -191,7 +191,7 @@ def judgeLanguage(sentence: str): def count_code(): """计算当前文件夹里面python代码的行数""" - files = os.listdir('.\\') + files = os.listdir('..\\') total = 0 for file in files: if not os.path.isfile(file): From 9deb6266c4b0c94935af6dd04ab0183eb46df97b Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Sat, 10 Oct 2020 09:29:33 +0800 Subject: [PATCH 10/28] =?UTF-8?q?=E6=94=B9=E5=8F=98=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- memorytools/globals.py | 3 +- memorytools/memorytools.py | 51 +++++++++-------- memorytools/plugins/alert/alert.py | 44 ++++++++------- memorytools/plugins/alert/config.json | 4 ++ memorytools/plugins/base.py | 35 +++++++++--- memorytools/{ => plugins}/config.json | 10 ++-- memorytools/plugins/copytrans/config.json | 8 +++ memorytools/plugins/copytrans/copytrans.py | 66 ++++++++++++---------- memorytools/plugins/ocr/config.json | 5 ++ memorytools/plugins/ocr/ocr.py | 40 +++++++------ memorytools/tools/config.py | 11 +++- memorytools/tools/utils.py | 64 ++++----------------- 12 files changed, 179 insertions(+), 162 deletions(-) create mode 100644 memorytools/plugins/alert/config.json rename memorytools/{ => plugins}/config.json (77%) create mode 100644 memorytools/plugins/copytrans/config.json create mode 100644 memorytools/plugins/ocr/config.json diff --git a/memorytools/globals.py b/memorytools/globals.py index 54a6378..e190186 100644 --- a/memorytools/globals.py +++ b/memorytools/globals.py @@ -17,8 +17,9 @@ class PATH: cwd = Path() + plugins = cwd / 'plugins' + config = plugins / 'config.json' icon = cwd / 'src' / 'icon' - config = cwd / 'config.json' log = cwd / 'log' diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index b43d43b..0f0c916 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -1,13 +1,11 @@ import webbrowser -from PIL import Image from globals import TEXT, ICON from time import sleep from plugins.ocr import OCR from plugins.alert import Alert from plugins.copytrans import CopyTrans from tools.systray import SysTrayIcon -from tools.config import Config -from tools.boxes import ImageBox +# from tools.config import Config class MemoryTool(object): @@ -16,15 +14,14 @@ class MemoryTool(object): """ def __init__(self): - self.icon = ICON.icon - self.config = Config() - config = self.config.readConfig() - copytrans = CopyTrans(self, config) - ocr = OCR(self, config) - alert = Alert(self, config) + # self.config = Config() + # config = self.config.readConfig() + copytrans = CopyTrans(self) + ocr = OCR(self) + alert = Alert(self) self.plugins = [copytrans, ocr, alert] - self.systray = SysTrayIcon(self.icon, TEXT.hover, self.createMenu(), + self.systray = SysTrayIcon(ICON.icon, TEXT.hover, self.createMenu(), on_quit=self.bye, default_menu_index=1, exit_ico=ICON.exit ) @@ -41,7 +38,7 @@ def createMenu(self): """ menu_options = [] for plugin in self.plugins: - menu_options.append(plugin.initMenu()) + menu_options.append(plugin.init_menu()) menu_options.append(('关于', ICON.about, self.about, True)) return tuple(menu_options) @@ -51,32 +48,36 @@ def refreshMenu(self): 刷新菜单 """ self.systray.refreshMenu(self.createMenu()) - self.refreshConfig() + # self.refreshConfig() - def refreshConfig(self) -> None: - """ - 写入设置 - """ - config = {} - for plugin in self.plugins: - name, con = plugin.getConfig() - config[name] = con - - self.config.writeConfig(config) + # def refreshConfig(self) -> None: + # """ + # 写入设置 + # """ + # config = {} + # for plugin in self.plugins: + # name, con = plugin.get_config() + # config[name] = con + # + # self.config.writeConfig(config) def about(self, s: SysTrayIcon): """ - 菜单中的 关于 选项,如果在线程中调用会出错,因此用一个变量控制,在主线程中显示信息 + 菜单中的 关于 选项 """ webbrowser.open("https://github.com/MemoryD/MemoryTools") def bye(self, s: SysTrayIcon): - """退出程序""" + """ + 退出程序 + """ self.end = True print('bye') def run(self): - """启动""" + """ + 启动主程序 + """ self.systray.start() while not self.end: sleep(0.1) diff --git a/memorytools/plugins/alert/alert.py b/memorytools/plugins/alert/alert.py index 1ad321e..50787e6 100644 --- a/memorytools/plugins/alert/alert.py +++ b/memorytools/plugins/alert/alert.py @@ -4,60 +4,64 @@ from globals import TEXT, ICON from tools.utils import isCheckIcon, isPickIcon from plugins import BasePlugin +from pathlib import Path class Alert(BasePlugin): - def __init__(self, root, config) -> None: - super(Alert, self).__init__("休息提醒", root, ICON.alert, config) + def __init__(self, root) -> None: + config_path = Path(__file__).parent / "config.json" + super(Alert, self).__init__("休息提醒", root, ICON.alert, config_path) self.start_time = time() - def getConfig(self) -> EasyDict: - return self.config - - def createMenu(self): + def create_menu(self): menu_options = ( - ("开启提醒", isCheckIcon(self.config.is_alert), self.pauseAlert, True), - ('30分钟', isPickIcon(self.config.alert_time == 30), self.changeTime30, False), - ('60分钟', isPickIcon(self.config.alert_time == 60), self.changeTime60, False), - ('90分钟', isPickIcon(self.config.alert_time == 90), self.changeTime90, False), - ('120分钟', isPickIcon(self.config.alert_time == 120), self.changeTime120, False), + ("开启提醒", isCheckIcon(self.is_alert), self.pauseAlert, True), + ('30分钟', isPickIcon(self.alert_time == 30), self.changeTime30, False), + ('60分钟', isPickIcon(self.alert_time == 60), self.changeTime60, False), + ('90分钟', isPickIcon(self.alert_time == 90), self.changeTime90, False), + ('120分钟', isPickIcon(self.alert_time == 120), self.changeTime120, False), ) return menu_options def alert(self): minute = (time() - self.start_time) / 60 # 分钟数 - if minute >= self.config.alert_time: + if minute >= self.alert_time: return True return False def pauseAlert(self, s): - self.config.is_alert = not self.config.is_alert - if self.config.is_alert: + self.is_alert = not self.is_alert + if self.is_alert: self.start_time = time() else: print("虽然你关掉了休息提醒,但还是要注意身体!") # LabelBox().show("虽然你关掉了休息提醒,但还是要注意身体!", "确定") + self.save_config() self.root.refreshMenu() def changeTime30(self, s): - self.config.alert_time = 30 + self.alert_time = 30 + self.save_config() self.root.refreshMenu() def changeTime60(self, s): - self.config.alert_time = 60 + self.alert_time = 60 + self.save_config() self.root.refreshMenu() def changeTime90(self, s): - self.config.alert_time = 90 + self.alert_time = 90 + self.save_config() self.root.refreshMenu() def changeTime120(self, s): - self.config.alert_time = 120 + self.alert_time = 120 + self.save_config() self.root.refreshMenu() def start(self): - if self.config.is_alert and self.alert(): - alert_message = TEXT.alert % self.config.alert_time + if self.is_alert and self.alert(): + alert_message = TEXT.alert % self.alert_time LabelBox('危险警报').show(alert_message, '等你想要继续工作了再点我') self.start_time = time() diff --git a/memorytools/plugins/alert/config.json b/memorytools/plugins/alert/config.json new file mode 100644 index 0000000..21b6219 --- /dev/null +++ b/memorytools/plugins/alert/config.json @@ -0,0 +1,4 @@ +{ + "is_alert": true, + "alert_time": 60 +} \ No newline at end of file diff --git a/memorytools/plugins/base.py b/memorytools/plugins/base.py index 8c81b2e..e8f42b4 100644 --- a/memorytools/plugins/base.py +++ b/memorytools/plugins/base.py @@ -1,18 +1,39 @@ +import json from easydict import EasyDict class BasePlugin(object): - def __init__(self, name: str, root, icon: str, config: EasyDict): + def __init__(self, name: str, root, icon: str, config_path): self.name = name self.root = root self.icon = icon - self.config = config[name] + self.config_path = config_path + self.config = self.init_config() - def getConfig(self) -> tuple: - return self.name, self.config + def init_config(self): + config = self.config_path.read_text(encoding="utf-8") + config = EasyDict(json.loads(config)) - def createMenu(self) -> tuple: + for attr, value in config.items(): + self.__setattr__(attr, value) + + return config + + def save_config(self): + for attr in self.config: + self.config[attr] = self.__getattribute__(attr) + + data = json.dumps(self.config, indent=4, ensure_ascii=False) + self.config_path.write_text(data, encoding="utf-8") + + # def create_default_config(self) -> EasyDict: + # raise NotImplementedError + + def create_menu(self) -> tuple: return () - def initMenu(self) -> tuple: - return self.name, self.icon, self.createMenu(), True + def init_menu(self) -> tuple: + return self.name, self.icon, self.create_menu(), True + + def start(self): + raise NotImplementedError diff --git a/memorytools/config.json b/memorytools/plugins/config.json similarity index 77% rename from memorytools/config.json rename to memorytools/plugins/config.json index e5bf1e7..f960ba2 100644 --- a/memorytools/config.json +++ b/memorytools/plugins/config.json @@ -1,10 +1,6 @@ { - "休息提醒": { - "is_alert": true, - "alert_time": 60 - }, "复制翻译": { - "is_trans": true, + "is_trans": false, "newline": false, "strict": false, "mode": "both", @@ -15,5 +11,9 @@ "is_ocr": false, "newline": false, "mode": "text" + }, + "休息提醒": { + "is_alert": false, + "alert_time": 30 } } \ No newline at end of file diff --git a/memorytools/plugins/copytrans/config.json b/memorytools/plugins/copytrans/config.json new file mode 100644 index 0000000..d1fda99 --- /dev/null +++ b/memorytools/plugins/copytrans/config.json @@ -0,0 +1,8 @@ +{ + "is_trans": true, + "newline": false, + "strict": false, + "mode": "both", + "src": "en", + "dest": "zh-cn" +} \ No newline at end of file diff --git a/memorytools/plugins/copytrans/copytrans.py b/memorytools/plugins/copytrans/copytrans.py index 46aba9e..1978111 100644 --- a/memorytools/plugins/copytrans/copytrans.py +++ b/memorytools/plugins/copytrans/copytrans.py @@ -1,3 +1,5 @@ +from pathlib import Path + from easydict import EasyDict from tools.boxes import TextTextBox @@ -9,54 +11,58 @@ class CopyTrans(BasePlugin): - def __init__(self, root, config: EasyDict) -> None: - super(CopyTrans, self).__init__("复制翻译", root, ICON.trans, config) + def __init__(self, root) -> None: + config_path = Path(__file__).parent / "config.json" + super(CopyTrans, self).__init__("复制翻译", root, ICON.trans, config_path) self.last = '' # 记录上次的剪切板内容 self.translator = Translator(service_urls=['translate.google.cn']) # 获得翻译接口 - def getConfig(self) -> EasyDict: - return self.config - - def createMenu(self) -> tuple: + def create_menu(self) -> tuple: menu_options = ( - ("开启翻译", isCheckIcon(self.config.is_trans), self.pauseTrans, True), - ('去除换行', isCheckIcon(not self.config.newline), self.turnNewline, True), - ('严格模式', isCheckIcon(self.config.strict), self.turnStrict, True), - ('英文 <-> 中文', isPickIcon(self.config.mode == 'both'), self.bothMode, False), - ('英文 --> 中文', isPickIcon(self.config.mode == 'en2zh'), self.en2zhMode, False), - ('中文 --> 英文', isPickIcon(self.config.mode == 'zh2en'), self.zh2enMode, False), + ("开启翻译", isCheckIcon(self.is_trans), self.pauseTrans, True), + ('去除换行', isCheckIcon(not self.newline), self.turnNewline, True), + ('严格模式', isCheckIcon(self.strict), self.turnStrict, True), + ('英文 <-> 中文', isPickIcon(self.mode == 'both'), self.bothMode, False), + ('英文 --> 中文', isPickIcon(self.mode == 'en2zh'), self.en2zhMode, False), + ('中文 --> 英文', isPickIcon(self.mode == 'zh2en'), self.zh2enMode, False), ) return menu_options def pauseTrans(self, sysTrayIcon): - self.config.is_trans = not self.config.is_trans + self.is_trans = not self.is_trans + self.save_config() self.root.refreshMenu() def en2zhMode(self, sysTrayIcon): - self.config.mode = 'en2zh' - self.config.src, self.config.dest = 'en', 'zh-cn' + self.mode = 'en2zh' + self.src, self.dest = 'en', 'zh-cn' + self.save_config() self.root.refreshMenu() def zh2enMode(self, sysTrayIcon): - self.config.mode = 'zh2en' - self.config.src, self.config.dest = 'zh-cn', 'en' + self.mode = 'zh2en' + self.src, self.dest = 'zh-cn', 'en' + self.save_config() self.root.refreshMenu() def bothMode(self, sysTrayIcon): - self.config.mode = 'both' + self.mode = 'both' + self.save_config() self.root.refreshMenu() def turnStrict(self, sysTrayIcon): - self.config.strict = not self.config.strict + self.strict = not self.strict + self.save_config() self.root.refreshMenu() def turnNewline(self, sysTrayIcon): - self.config.newline = not self.config.newline + self.newline = not self.newline + self.save_config() self.root.refreshMenu() def removeNewline(self, source): - if not self.config.newline: + if not self.newline: sentence = source.replace("\r", '').replace("\n", " ") else: sentence = source @@ -76,17 +82,17 @@ def preProcess(self, source): return None text = source.strip() src_language, score = judgeLanguage(text) - print('检测为:%s, %s. 目标语言为:%s' % (src_language, score, self.config.dest)) + print('检测为:%s, %s. 目标语言为:%s' % (src_language, score, self.dest)) if not src_language: self.last = source return None - if self.config.mode != 'both' and src_language == self.config.dest and score > 0.8: + if self.mode != 'both' and src_language == self.dest and score > 0.8: self.last = source return None - if self.config.mode == 'both': - self.config.src = src_language - self.config.dest = 'en' if src_language == 'zh-cn' else 'zh-cn' + if self.mode == 'both': + self.src = src_language + self.dest = 'en' if src_language == 'zh-cn' else 'zh-cn' sentence = self.removeNewline(text) @@ -95,10 +101,10 @@ def preProcess(self, source): def transText(self, sentence: str): for i in range(3): try: - if self.config.strict: - text = self.translator.translate(sentence, src=self.config.src, dest=self.config.dest).text + if self.strict: + text = self.translator.translate(sentence, src=self.src, dest=self.dest).text else: - text = self.translator.translate(sentence, dest=self.config.dest).text + text = self.translator.translate(sentence, dest=self.dest).text return text except ConnectionError as ce: print(ce) @@ -128,7 +134,7 @@ def trans(self, source: str): self.last = pasteClip() def start(self): - if not self.config.is_trans: # 是否暂停 + if not self.is_trans: # 是否暂停 return source = pasteClip() # 获得剪切板内容 self.trans(source) diff --git a/memorytools/plugins/ocr/config.json b/memorytools/plugins/ocr/config.json new file mode 100644 index 0000000..05abadf --- /dev/null +++ b/memorytools/plugins/ocr/config.json @@ -0,0 +1,5 @@ +{ + "is_ocr": false, + "newline": false, + "mode": "text" +} diff --git a/memorytools/plugins/ocr/ocr.py b/memorytools/plugins/ocr/ocr.py index 0a5116e..fae37e4 100644 --- a/memorytools/plugins/ocr/ocr.py +++ b/memorytools/plugins/ocr/ocr.py @@ -1,3 +1,5 @@ +from pathlib import Path + from easydict import EasyDict from . import BaiduOCR from . import LatexOCR @@ -9,50 +11,52 @@ class OCR(BasePlugin): - def __init__(self, root, config): - super(OCR, self).__init__("OCR识别", root, ICON.ocr, config) + def __init__(self, root): + config_path = Path(__file__).parent / "config.json" + super(OCR, self).__init__("OCR识别", root, ICON.ocr, config_path) self.textocr = BaiduOCR(BAIDU_ACCOUNTS) self.mathocr = LatexOCR(XUEERSI_ACCOUNTS) - def getConfig(self) -> EasyDict: - return self.config - - def createMenu(self) -> tuple: + def create_menu(self) -> tuple: menu_options = ( - ("开启OCR", isCheckIcon(self.config.is_ocr), self.pauseOcr, True), - ('去除换行', isCheckIcon(not self.config.newline), self.turnNewline, True), - ('识别文本', isPickIcon(self.config.mode == 'text'), self.textMode, False), - ('识别公式', isPickIcon(self.config.mode == 'math'), self.mathMode, False), + ("开启OCR", isCheckIcon(self.is_ocr), self.pauseOcr, True), + ('去除换行', isCheckIcon(not self.newline), self.turnNewline, True), + ('识别文本', isPickIcon(self.mode == 'text'), self.textMode, False), + ('识别公式', isPickIcon(self.mode == 'math'), self.mathMode, False), ) return menu_options def pauseOcr(self, sysTrayIcon): - self.config.is_ocr = not self.config.is_ocr + self.is_ocr = not self.is_ocr + self.save_config() self.root.refreshMenu() def textMode(self, sysTrayIcon): - self.config.mode = 'text' + self.mode = 'text' + self.save_config() self.root.refreshMenu() def mathMode(self, sysTrayIcon): - self.config.mode = 'math' + self.mode = 'math' + self.save_config() self.root.refreshMenu() def turnNewline(self, sysTrayIcon): - self.config.newline = not self.config.newline + self.newline = not self.newline + self.save_config() self.root.refreshMenu() def start(self): - if not self.config.is_ocr: + if not self.is_ocr: return im = ImageGrab.grabclipboard() # 获取剪切板 if isinstance(im, Image.Image): # 判断是否是图片 try: - if self.config.mode == 'text': - text = self.textocr.ocr(im, self.config.newline) - elif self.config.mode == 'math': + if self.mode == 'text': + text = self.textocr.ocr(im, self.newline) + elif self.mode == 'math': pos, text = self.mathocr.latex(im) print("位置:", pos) draw = ImageDraw.Draw(im) diff --git a/memorytools/tools/config.py b/memorytools/tools/config.py index 721e390..2362193 100644 --- a/memorytools/tools/config.py +++ b/memorytools/tools/config.py @@ -1,17 +1,22 @@ import json +from pathlib import Path from easydict import EasyDict from globals import PATH -class Config(object): - def __init__(self, path=PATH.config): +class Configer(object): + def __init__(self, path: Path, default=None): self.path = path + self.default = default def readConfig(self) -> EasyDict: """ 读配置文件 """ - config = self.path.read_text(encoding="utf-8") + if self.path.exists: + config = self.path.read_text(encoding="utf-8") + else: + config = self.default return EasyDict(json.loads(config)) def writeConfig(self, data: dict): diff --git a/memorytools/tools/utils.py b/memorytools/tools/utils.py index 60302fc..11a4f35 100644 --- a/memorytools/tools/utils.py +++ b/memorytools/tools/utils.py @@ -1,8 +1,7 @@ import os import re -import json +import pyperclip from time import sleep -from pyperclip import paste, copy from base64 import b64decode, b64encode from urllib.parse import quote from io import BytesIO @@ -11,6 +10,9 @@ class Color(object): + """ + 一个简单的获取颜色的类 + """ def __init__(self): self.colors = COLOR self.index = 0 @@ -22,9 +24,13 @@ def next(self): def pasteClip(): + """ + 获取剪切板内容,为了防止获取失败,因此会重试3次 + :return: + """ for i in range(3): try: - text = paste() + text = pyperclip.paste() return text except Exception as e: if i == 2: @@ -34,7 +40,7 @@ def pasteClip(): def copyClip(text): try: - copy(text) + pyperclip.copy(text) except Exception as e: print(e) @@ -84,20 +90,6 @@ def resizeImg(img, max_w: int, max_h: int): return img -# def getSrc(pic: str): -# """返回对应资源的完整路径""" -# path = os.path.join(ICON_PATH, pic) -# file = os.path.abspath(path) -# -# if not os.path.exists(ICON_PATH): -# os.makedirs(ICON_PATH) -# if not os.path.exists(file): -# if pic in ICONS: -# bs64toImg(ICONS[pic], file) -# -# return file - - def isCheckIcon(check: bool): """是否选中(两种状态)""" return ICON.check if check else None @@ -117,40 +109,6 @@ def img2base64(image: str): return image_data_base64 -# def readConfig(config=PATH.config) -> EasyDict: -# """ -# 读配置文件 -# """ -# if config == PATH.config and not os.path.exists(name): -# resetConfig() -# try: -# with open(name, "r", encoding="utf-8") as f: -# data = f.read() -# return EasyDict(json.loads(data)) -# except Exception as e: -# print(e) -# return DEFAULT_CONFIG -# -# -# def writeConfig(data: dict, name=CONFIG): -# """ -# 写配置文件 -# """ -# try: -# data = json.dumps(data, indent=4, ensure_ascii=False) -# with open(name, "w", encoding="utf-8") as f: -# f.write(data) -# except Exception as e: -# print(e) -# -# -# def resetConfig(name=CONFIG): -# """ -# 重置配置文件 -# """ -# writeConfig(DEFAULT_CONFIG, name) - - def filterStr(sentence: str): """ 过滤掉字符串中的标点符号 @@ -169,7 +127,7 @@ def judgeLanguage(sentence: str): sentence = filterStr(sentence) if sentence == '': - return (None, 0) + return None, 0 en_pattern = re.compile(u"[a-zA-Z]") zh_pattern = re.compile(u"[\u4e00-\u9fa5]") From d80427391f27c0897eaf4fd7b1e5bac8c5a9cbab Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Sat, 10 Oct 2020 09:48:01 +0800 Subject: [PATCH 11/28] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E8=A3=85=E9=A5=B0?= =?UTF-8?q?=E5=99=A8=E6=9B=B4=E6=94=B9=E8=8F=9C=E5=8D=95=E5=92=8C=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- memorytools/plugins/__init__.py | 2 +- memorytools/plugins/alert/alert.py | 17 ++++++----------- memorytools/plugins/alert/config.json | 4 ++-- memorytools/plugins/base.py | 16 ++++++++++++++++ memorytools/plugins/copytrans/copytrans.py | 20 +++++++------------- memorytools/plugins/ocr/ocr.py | 22 +++++++++------------- 6 files changed, 41 insertions(+), 40 deletions(-) diff --git a/memorytools/plugins/__init__.py b/memorytools/plugins/__init__.py index 8d39251..9a83a08 100644 --- a/memorytools/plugins/__init__.py +++ b/memorytools/plugins/__init__.py @@ -1,5 +1,5 @@ from pathlib import Path -from .base import BasePlugin +from .base import BasePlugin, change_config # plugin_path = Path() / "plugins" diff --git a/memorytools/plugins/alert/alert.py b/memorytools/plugins/alert/alert.py index 50787e6..21281ac 100644 --- a/memorytools/plugins/alert/alert.py +++ b/memorytools/plugins/alert/alert.py @@ -3,7 +3,7 @@ from tools.boxes import LabelBox from globals import TEXT, ICON from tools.utils import isCheckIcon, isPickIcon -from plugins import BasePlugin +from plugins import BasePlugin, change_config from pathlib import Path @@ -30,6 +30,7 @@ def alert(self): return True return False + @change_config def pauseAlert(self, s): self.is_alert = not self.is_alert if self.is_alert: @@ -37,28 +38,22 @@ def pauseAlert(self, s): else: print("虽然你关掉了休息提醒,但还是要注意身体!") # LabelBox().show("虽然你关掉了休息提醒,但还是要注意身体!", "确定") - self.save_config() - self.root.refreshMenu() + @change_config def changeTime30(self, s): self.alert_time = 30 - self.save_config() - self.root.refreshMenu() + @change_config def changeTime60(self, s): self.alert_time = 60 - self.save_config() - self.root.refreshMenu() + @change_config def changeTime90(self, s): self.alert_time = 90 - self.save_config() - self.root.refreshMenu() + @change_config def changeTime120(self, s): self.alert_time = 120 - self.save_config() - self.root.refreshMenu() def start(self): if self.is_alert and self.alert(): diff --git a/memorytools/plugins/alert/config.json b/memorytools/plugins/alert/config.json index 21b6219..9ff2635 100644 --- a/memorytools/plugins/alert/config.json +++ b/memorytools/plugins/alert/config.json @@ -1,4 +1,4 @@ { - "is_alert": true, - "alert_time": 60 + "is_alert": false, + "alert_time": 90 } \ No newline at end of file diff --git a/memorytools/plugins/base.py b/memorytools/plugins/base.py index e8f42b4..341031e 100644 --- a/memorytools/plugins/base.py +++ b/memorytools/plugins/base.py @@ -2,6 +2,22 @@ from easydict import EasyDict +def change_config(set_attr): + """ + 因为每次更改属性都要刷新托盘菜单,并且写到配置文件中, + 所以定义一个装饰器,以简化代码 + :param set_attr: 更改属性的函数 + :return: 装饰过的函数 + """ + def wrapper(plugin, s): + f = set_attr(plugin, s) + plugin.save_config() + plugin.root.refreshMenu() + return f + + return wrapper + + class BasePlugin(object): def __init__(self, name: str, root, icon: str, config_path): self.name = name diff --git a/memorytools/plugins/copytrans/copytrans.py b/memorytools/plugins/copytrans/copytrans.py index 1978111..f47b059 100644 --- a/memorytools/plugins/copytrans/copytrans.py +++ b/memorytools/plugins/copytrans/copytrans.py @@ -6,7 +6,7 @@ from googletransx import Translator from tools.utils import isCheckIcon, isPickIcon, judgeLanguage, pasteClip from requests.exceptions import ConnectionError -from plugins import BasePlugin +from plugins import BasePlugin, change_config from globals import ICON @@ -29,37 +29,31 @@ def create_menu(self) -> tuple: return menu_options + @change_config def pauseTrans(self, sysTrayIcon): self.is_trans = not self.is_trans - self.save_config() - self.root.refreshMenu() + @change_config def en2zhMode(self, sysTrayIcon): self.mode = 'en2zh' self.src, self.dest = 'en', 'zh-cn' - self.save_config() - self.root.refreshMenu() + @change_config def zh2enMode(self, sysTrayIcon): self.mode = 'zh2en' self.src, self.dest = 'zh-cn', 'en' - self.save_config() - self.root.refreshMenu() + @change_config def bothMode(self, sysTrayIcon): self.mode = 'both' - self.save_config() - self.root.refreshMenu() + @change_config def turnStrict(self, sysTrayIcon): self.strict = not self.strict - self.save_config() - self.root.refreshMenu() + @change_config def turnNewline(self, sysTrayIcon): self.newline = not self.newline - self.save_config() - self.root.refreshMenu() def removeNewline(self, source): if not self.newline: diff --git a/memorytools/plugins/ocr/ocr.py b/memorytools/plugins/ocr/ocr.py index fae37e4..9733293 100644 --- a/memorytools/plugins/ocr/ocr.py +++ b/memorytools/plugins/ocr/ocr.py @@ -7,7 +7,7 @@ from tools.boxes import ImageTextBox from globals import BAIDU_ACCOUNTS, XUEERSI_ACCOUNTS, ICON from tools.utils import isCheckIcon, isPickIcon, getRect, Color, copyClip -from plugins import BasePlugin +from plugins import BasePlugin, change_config class OCR(BasePlugin): @@ -27,25 +27,21 @@ def create_menu(self) -> tuple: return menu_options - def pauseOcr(self, sysTrayIcon): + @change_config + def pauseOcr(self, s): self.is_ocr = not self.is_ocr - self.save_config() - self.root.refreshMenu() - def textMode(self, sysTrayIcon): + @change_config + def textMode(self, s): self.mode = 'text' - self.save_config() - self.root.refreshMenu() - def mathMode(self, sysTrayIcon): + @change_config + def mathMode(self, s): self.mode = 'math' - self.save_config() - self.root.refreshMenu() - def turnNewline(self, sysTrayIcon): + @change_config + def turnNewline(self, s): self.newline = not self.newline - self.save_config() - self.root.refreshMenu() def start(self): if not self.is_ocr: From c2eeb81055dfea2f4b5e709d54b6efd365b26c4d Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Sat, 10 Oct 2020 10:09:27 +0800 Subject: [PATCH 12/28] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E7=9A=84=E5=91=BD=E5=90=8D=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- memorytools/memorytools.py | 25 +++--------- memorytools/plugins/alert/alert.py | 34 ++++++++-------- memorytools/plugins/alert/config.json | 2 +- memorytools/plugins/base.py | 2 +- memorytools/plugins/copytrans/copytrans.py | 46 +++++++++++----------- memorytools/plugins/ocr/ocr.py | 31 +++++++-------- memorytools/tools/boxes.py | 26 ++++++------ memorytools/tools/config.py | 28 ------------- memorytools/tools/utils.py | 40 +++++++++---------- 9 files changed, 94 insertions(+), 140 deletions(-) delete mode 100644 memorytools/tools/config.py diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index 0f0c916..fd43b51 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -1,11 +1,10 @@ import webbrowser -from globals import TEXT, ICON from time import sleep +from globals import TEXT, ICON from plugins.ocr import OCR from plugins.alert import Alert from plugins.copytrans import CopyTrans from tools.systray import SysTrayIcon -# from tools.config import Config class MemoryTool(object): @@ -14,21 +13,19 @@ class MemoryTool(object): """ def __init__(self): - # self.config = Config() - # config = self.config.readConfig() copytrans = CopyTrans(self) ocr = OCR(self) alert = Alert(self) self.plugins = [copytrans, ocr, alert] - self.systray = SysTrayIcon(ICON.icon, TEXT.hover, self.createMenu(), + self.systray = SysTrayIcon(ICON.icon, TEXT.hover, self.create_menu(), on_quit=self.bye, default_menu_index=1, exit_ico=ICON.exit ) self.end = False - def createMenu(self): + def create_menu(self): """创建托盘程序的菜单 菜单中的每一项为元组,每个元组含义如下: 第 1 项:菜单项名称 @@ -43,23 +40,11 @@ def createMenu(self): return tuple(menu_options) - def refreshMenu(self): + def refresh_menu(self): """ 刷新菜单 """ - self.systray.refreshMenu(self.createMenu()) - # self.refreshConfig() - - # def refreshConfig(self) -> None: - # """ - # 写入设置 - # """ - # config = {} - # for plugin in self.plugins: - # name, con = plugin.get_config() - # config[name] = con - # - # self.config.writeConfig(config) + self.systray.refreshMenu(self.create_menu()) def about(self, s: SysTrayIcon): """ diff --git a/memorytools/plugins/alert/alert.py b/memorytools/plugins/alert/alert.py index 21281ac..2ccaf90 100644 --- a/memorytools/plugins/alert/alert.py +++ b/memorytools/plugins/alert/alert.py @@ -2,7 +2,7 @@ from easydict import EasyDict from tools.boxes import LabelBox from globals import TEXT, ICON -from tools.utils import isCheckIcon, isPickIcon +from tools.utils import is_check, is_pick from plugins import BasePlugin, change_config from pathlib import Path @@ -15,23 +15,17 @@ def __init__(self, root) -> None: def create_menu(self): menu_options = ( - ("开启提醒", isCheckIcon(self.is_alert), self.pauseAlert, True), - ('30分钟', isPickIcon(self.alert_time == 30), self.changeTime30, False), - ('60分钟', isPickIcon(self.alert_time == 60), self.changeTime60, False), - ('90分钟', isPickIcon(self.alert_time == 90), self.changeTime90, False), - ('120分钟', isPickIcon(self.alert_time == 120), self.changeTime120, False), + ("开启提醒", is_check(self.is_alert), self.pause_alert, True), + ('30分钟', is_pick(self.alert_time == 30), self.set_alert_time_30, False), + ('60分钟', is_pick(self.alert_time == 60), self.set_alert_time_60, False), + ('90分钟', is_pick(self.alert_time == 90), self.set_alert_time_90, False), + ('120分钟', is_pick(self.alert_time == 120), self.set_alert_time_120, False), ) return menu_options - def alert(self): - minute = (time() - self.start_time) / 60 # 分钟数 - if minute >= self.alert_time: - return True - return False - @change_config - def pauseAlert(self, s): + def pause_alert(self, s): self.is_alert = not self.is_alert if self.is_alert: self.start_time = time() @@ -40,21 +34,27 @@ def pauseAlert(self, s): # LabelBox().show("虽然你关掉了休息提醒,但还是要注意身体!", "确定") @change_config - def changeTime30(self, s): + def set_alert_time_30(self, s): self.alert_time = 30 @change_config - def changeTime60(self, s): + def set_alert_time_60(self, s): self.alert_time = 60 @change_config - def changeTime90(self, s): + def set_alert_time_90(self, s): self.alert_time = 90 @change_config - def changeTime120(self, s): + def set_alert_time_120(self, s): self.alert_time = 120 + def alert(self): + minute = (time() - self.start_time) / 60 # 分钟数 + if minute >= self.alert_time: + return True + return False + def start(self): if self.is_alert and self.alert(): alert_message = TEXT.alert % self.alert_time diff --git a/memorytools/plugins/alert/config.json b/memorytools/plugins/alert/config.json index 9ff2635..664824e 100644 --- a/memorytools/plugins/alert/config.json +++ b/memorytools/plugins/alert/config.json @@ -1,4 +1,4 @@ { - "is_alert": false, + "is_alert": true, "alert_time": 90 } \ No newline at end of file diff --git a/memorytools/plugins/base.py b/memorytools/plugins/base.py index 341031e..162da57 100644 --- a/memorytools/plugins/base.py +++ b/memorytools/plugins/base.py @@ -12,7 +12,7 @@ def change_config(set_attr): def wrapper(plugin, s): f = set_attr(plugin, s) plugin.save_config() - plugin.root.refreshMenu() + plugin.root.refresh_menu() return f return wrapper diff --git a/memorytools/plugins/copytrans/copytrans.py b/memorytools/plugins/copytrans/copytrans.py index f47b059..2c7314d 100644 --- a/memorytools/plugins/copytrans/copytrans.py +++ b/memorytools/plugins/copytrans/copytrans.py @@ -1,10 +1,8 @@ from pathlib import Path - from easydict import EasyDict - from tools.boxes import TextTextBox from googletransx import Translator -from tools.utils import isCheckIcon, isPickIcon, judgeLanguage, pasteClip +from tools.utils import is_check, is_pick, judge_language, paste_clip from requests.exceptions import ConnectionError from plugins import BasePlugin, change_config from globals import ICON @@ -19,43 +17,43 @@ def __init__(self, root) -> None: def create_menu(self) -> tuple: menu_options = ( - ("开启翻译", isCheckIcon(self.is_trans), self.pauseTrans, True), - ('去除换行', isCheckIcon(not self.newline), self.turnNewline, True), - ('严格模式', isCheckIcon(self.strict), self.turnStrict, True), - ('英文 <-> 中文', isPickIcon(self.mode == 'both'), self.bothMode, False), - ('英文 --> 中文', isPickIcon(self.mode == 'en2zh'), self.en2zhMode, False), - ('中文 --> 英文', isPickIcon(self.mode == 'zh2en'), self.zh2enMode, False), + ("开启翻译", is_check(self.is_trans), self.pause_trans, True), + ('去除换行', is_check(not self.newline), self.turn_newline, True), + ('严格模式', is_check(self.strict), self.turn_strict, True), + ('英文 <-> 中文', is_pick(self.mode == 'both'), self.both_mode, False), + ('英文 --> 中文', is_pick(self.mode == 'en2zh'), self.en2zh_mode, False), + ('中文 --> 英文', is_pick(self.mode == 'zh2en'), self.zh2en_mode, False), ) return menu_options @change_config - def pauseTrans(self, sysTrayIcon): + def pause_trans(self, s): self.is_trans = not self.is_trans @change_config - def en2zhMode(self, sysTrayIcon): + def en2zh_mode(self, s): self.mode = 'en2zh' self.src, self.dest = 'en', 'zh-cn' @change_config - def zh2enMode(self, sysTrayIcon): + def zh2en_mode(self, s): self.mode = 'zh2en' self.src, self.dest = 'zh-cn', 'en' @change_config - def bothMode(self, sysTrayIcon): + def both_mode(self, s): self.mode = 'both' @change_config - def turnStrict(self, sysTrayIcon): + def turn_strict(self, s): self.strict = not self.strict @change_config - def turnNewline(self, sysTrayIcon): + def turn_newline(self, s): self.newline = not self.newline - def removeNewline(self, source): + def remove_newline(self, source): if not self.newline: sentence = source.replace("\r", '').replace("\n", " ") else: @@ -63,7 +61,7 @@ def removeNewline(self, source): return sentence - def preProcess(self, source): + def pre_process(self, source): ''' 对剪切板的文本进行预处理。 首先判断是否为空或者与上次复制的一致,如果是则不翻译。 @@ -75,7 +73,7 @@ def preProcess(self, source): if source == "" or source == self.last: return None text = source.strip() - src_language, score = judgeLanguage(text) + src_language, score = judge_language(text) print('检测为:%s, %s. 目标语言为:%s' % (src_language, score, self.dest)) if not src_language: self.last = source @@ -88,11 +86,11 @@ def preProcess(self, source): self.src = src_language self.dest = 'en' if src_language == 'zh-cn' else 'zh-cn' - sentence = self.removeNewline(text) + sentence = self.remove_newline(text) return sentence - def transText(self, sentence: str): + def trans_text(self, sentence: str): for i in range(3): try: if self.strict: @@ -110,11 +108,11 @@ def transText(self, sentence: str): return text def trans(self, source: str): - sentence = self.preProcess(source) + sentence = self.pre_process(source) if not sentence: return None - text = self.transText(sentence) + text = self.trans_text(sentence) if text == sentence: self.last = source @@ -125,10 +123,10 @@ def trans(self, source: str): # paste = pasteClip() # if paste == source: # copyClip(sentence) - self.last = pasteClip() + self.last = paste_clip() def start(self): if not self.is_trans: # 是否暂停 return - source = pasteClip() # 获得剪切板内容 + source = paste_clip() # 获得剪切板内容 self.trans(source) diff --git a/memorytools/plugins/ocr/ocr.py b/memorytools/plugins/ocr/ocr.py index 9733293..1935e92 100644 --- a/memorytools/plugins/ocr/ocr.py +++ b/memorytools/plugins/ocr/ocr.py @@ -1,12 +1,11 @@ from pathlib import Path - from easydict import EasyDict from . import BaiduOCR from . import LatexOCR from PIL import Image, ImageGrab, ImageDraw from tools.boxes import ImageTextBox from globals import BAIDU_ACCOUNTS, XUEERSI_ACCOUNTS, ICON -from tools.utils import isCheckIcon, isPickIcon, getRect, Color, copyClip +from tools.utils import is_check, is_pick, get_rect, Color, copy_clip from plugins import BasePlugin, change_config @@ -14,33 +13,33 @@ class OCR(BasePlugin): def __init__(self, root): config_path = Path(__file__).parent / "config.json" super(OCR, self).__init__("OCR识别", root, ICON.ocr, config_path) - self.textocr = BaiduOCR(BAIDU_ACCOUNTS) - self.mathocr = LatexOCR(XUEERSI_ACCOUNTS) + self.text_ocr = BaiduOCR(BAIDU_ACCOUNTS) + self.math_ocr = LatexOCR(XUEERSI_ACCOUNTS) def create_menu(self) -> tuple: menu_options = ( - ("开启OCR", isCheckIcon(self.is_ocr), self.pauseOcr, True), - ('去除换行', isCheckIcon(not self.newline), self.turnNewline, True), - ('识别文本', isPickIcon(self.mode == 'text'), self.textMode, False), - ('识别公式', isPickIcon(self.mode == 'math'), self.mathMode, False), + ("开启OCR", is_check(self.is_ocr), self.pause_ocr, True), + ('去除换行', is_check(not self.newline), self.turn_newline, True), + ('识别文本', is_pick(self.mode == 'text'), self.text_mode, False), + ('识别公式', is_pick(self.mode == 'math'), self.math_mode, False), ) return menu_options @change_config - def pauseOcr(self, s): + def pause_ocr(self, s): self.is_ocr = not self.is_ocr @change_config - def textMode(self, s): + def text_mode(self, s): self.mode = 'text' @change_config - def mathMode(self, s): + def math_mode(self, s): self.mode = 'math' @change_config - def turnNewline(self, s): + def turn_newline(self, s): self.newline = not self.newline def start(self): @@ -51,18 +50,18 @@ def start(self): if isinstance(im, Image.Image): # 判断是否是图片 try: if self.mode == 'text': - text = self.textocr.ocr(im, self.newline) + text = self.text_ocr.ocr(im, self.newline) elif self.mode == 'math': - pos, text = self.mathocr.latex(im) + pos, text = self.math_ocr.latex(im) print("位置:", pos) draw = ImageDraw.Draw(im) color = Color() for rect in pos: - draw.polygon(getRect(*rect), outline=color.next()) + draw.polygon(get_rect(*rect), outline=color.next()) except Exception as e: text = str(e) - copyClip('') + copy_clip('') ImageTextBox('OCR识别结果').show(im, text) diff --git a/memorytools/tools/boxes.py b/memorytools/tools/boxes.py index 12e5a5f..0727519 100644 --- a/memorytools/tools/boxes.py +++ b/memorytools/tools/boxes.py @@ -8,7 +8,7 @@ from tkinter import Tk, END from tkinter.ttk import Label, Button, Frame from tkinter.scrolledtext import ScrolledText, Text -from tools.utils import getTextLine, resizeImg, copyClip +from tools.utils import get_text_line, resize_img, copy_clip from globals import ICON @@ -16,10 +16,10 @@ class BaseBox(Tk): """弹出框的基类""" def __init__(self, buttons=[], title='Memory Tools'): super(BaseBox, self).__init__() - self.setWindow(title) - self.setButton(buttons) + self.set_window(title) + self.set_button(buttons) - def setWindow(self, title: str): + def set_window(self, title: str): self.screen_w = self.winfo_screenwidth() self.screen_h = self.winfo_screenheight() self.title(title) @@ -30,7 +30,7 @@ def setWindow(self, title: str): min_h = self.screen_h // 3 self.minsize(min_w, min_h) - def setButton(self, buttons: list): + def set_button(self, buttons: list): ''' 定义底部按钮 ''' @@ -58,7 +58,7 @@ def start(self, show=True): def copy(self): txt = self.textbox.get("1.0", END) - copyClip(txt) + copy_clip(txt) self.destroy() @@ -68,8 +68,8 @@ def __init__(self, title='MemoryBox'): super(TextTextBox, self).__init__(buttons, title) def show(self, src: str, dest: str): - h1 = min(10, max(5, getTextLine(src)+1)) - h2 = min(10, max(5, getTextLine(dest)+1)) + h1 = min(10, max(5, get_text_line(src) + 1)) + h2 = min(10, max(5, get_text_line(dest) + 1)) self.src_text = ScrolledText(self, height=h1, background='#ffffff', font=("微软雅黑", 11)) self.textbox = ScrolledText(self, height=h2, background='#ffffff', font=("微软雅黑", 11)) @@ -89,7 +89,7 @@ def __init__(self, title='MemoryBox'): super(ImageBox, self).__init__([], title) def show(self, img): - img = resizeImg(img, self.screen_w//3, 100000) + img = resize_img(img, self.screen_w // 3, 100000) w, h = img.size self.geometry('%dx%d' % (w+20, self.screen_h*2//3)) image = ImageTk.PhotoImage(image=img) @@ -120,7 +120,7 @@ def __init__(self, title='MemoryBox'): buttons = [('复制', self.copy), ] super(ImageTextBox, self).__init__(buttons, title) - def setSize(self, img): + def set_size(self, img): ''' 对图片进行处理,并限制窗口大小 ''' @@ -129,13 +129,13 @@ def setSize(self, img): if img_w > img_h * aspect_ratio: w, h = self.screen_w * 0.9, self.screen_h * 0.35 - img = resizeImg(img, w, h) + img = resize_img(img, w, h) img_w, img_h = img.size width = max(self.screen_w // 3, img_w+20) self.maxsize(width, int(self.screen_h*0.9)) else: w, h = self.screen_w * 0.45, self.screen_h * 0.7 - img = resizeImg(img, w, h) + img = resize_img(img, w, h) img_w, img_h = img.size width = max(self.screen_w // 3, 2 * img_w + 70) self.maxsize(width, int(self.screen_h*0.9)) @@ -146,7 +146,7 @@ def show(self, img, txt: str): ''' 显示 ''' - img = self.setSize(img) + img = self.set_size(img) w, h = img.size self.tkImage = ImageTk.PhotoImage(image=img) diff --git a/memorytools/tools/config.py b/memorytools/tools/config.py deleted file mode 100644 index 2362193..0000000 --- a/memorytools/tools/config.py +++ /dev/null @@ -1,28 +0,0 @@ -import json -from pathlib import Path -from easydict import EasyDict -from globals import PATH - - -class Configer(object): - def __init__(self, path: Path, default=None): - self.path = path - self.default = default - - def readConfig(self) -> EasyDict: - """ - 读配置文件 - """ - if self.path.exists: - config = self.path.read_text(encoding="utf-8") - else: - config = self.default - return EasyDict(json.loads(config)) - - def writeConfig(self, data: dict): - """ - 写配置文件 - """ - config = json.dumps(data, indent=4, ensure_ascii=False) - self.path.write_text(config, encoding="utf-8") - diff --git a/memorytools/tools/utils.py b/memorytools/tools/utils.py index 11a4f35..713f67d 100644 --- a/memorytools/tools/utils.py +++ b/memorytools/tools/utils.py @@ -23,7 +23,7 @@ def next(self): return color -def pasteClip(): +def paste_clip(): """ 获取剪切板内容,为了防止获取失败,因此会重试3次 :return: @@ -38,19 +38,19 @@ def pasteClip(): sleep(0.1) -def copyClip(text): +def copy_clip(text): try: pyperclip.copy(text) except Exception as e: print(e) -def getTextLine(text: str): +def get_text_line(text: str): """返回所给的文本有几行""" return len(text.split('\n')) -def getRect(x1: int, y1: int, x2: int, y2: int): +def get_rect(x1: int, y1: int, x2: int, y2: int): """给定矩形框的左上角和右下角坐标,返回四个角的坐标""" return [(x1, y1), (x2, y1), (x2, y2), (x1, y2)] @@ -64,13 +64,22 @@ def pil2bytes(im, img_type='png', b64=False): return img -def bs64toImg(pic_code, pic_name): +def bs64_to_img(pic_code, pic_name): """将bs64编码的数据写到文件中""" with open(pic_name, 'wb') as image: image.write(b64decode(pic_code)) -def resizeImg(img, max_w: int, max_h: int): +def img_to_base64(image: str): + """将图像从文件中读取出来并转化为base64编码""" + with open(image, 'rb') as bin_data: + image_data = bin_data.read() + image_data_base64 = b64encode(image_data) + image_data_base64 = quote(image_data_base64) + return image_data_base64 + + +def resize_img(img, max_w: int, max_h: int): """ 对img进行缩放,使其长宽不超过给定的 max_w 和 max_h """ @@ -90,26 +99,17 @@ def resizeImg(img, max_w: int, max_h: int): return img -def isCheckIcon(check: bool): +def is_check(check: bool): """是否选中(两种状态)""" return ICON.check if check else None -def isPickIcon(pick: bool): +def is_pick(pick: bool): """是否被选中(多项中的一个)""" return ICON.pick if pick else None -def img2base64(image: str): - """将图像从文件中读取出来并转化为base64编码""" - with open(image, 'rb') as bin_data: - image_data = bin_data.read() - image_data_base64 = b64encode(image_data) - image_data_base64 = quote(image_data_base64) - return image_data_base64 - - -def filterStr(sentence: str): +def filter_str(sentence: str): """ 过滤掉字符串中的标点符号 """ @@ -120,11 +120,11 @@ def filterStr(sentence: str): return sentence -def judgeLanguage(sentence: str): +def judge_language(sentence: str): """ 判断一句话里面英文和中文的占比 """ - sentence = filterStr(sentence) + sentence = filter_str(sentence) if sentence == '': return None, 0 From 863cee42c796a278c5f40cba955726756626618a Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Sat, 10 Oct 2020 10:23:34 +0800 Subject: [PATCH 13/28] =?UTF-8?q?=E5=8A=A8=E6=80=81=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- memorytools/memorytools.py | 9 ++------- memorytools/plugins/__init__.py | 20 ++++++++++---------- memorytools/plugins/alert/__init__.py | 2 +- memorytools/plugins/alert/alert.py | 1 + memorytools/plugins/copytrans/__init__.py | 2 +- memorytools/plugins/ocr/__init__.py | 2 +- 6 files changed, 16 insertions(+), 20 deletions(-) diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index fd43b51..cca5240 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -1,9 +1,7 @@ import webbrowser from time import sleep from globals import TEXT, ICON -from plugins.ocr import OCR -from plugins.alert import Alert -from plugins.copytrans import CopyTrans +from plugins import plugin_list from tools.systray import SysTrayIcon @@ -13,10 +11,7 @@ class MemoryTool(object): """ def __init__(self): - copytrans = CopyTrans(self) - ocr = OCR(self) - alert = Alert(self) - self.plugins = [copytrans, ocr, alert] + self.plugins = [plugin(self) for plugin in plugin_list] self.systray = SysTrayIcon(ICON.icon, TEXT.hover, self.create_menu(), on_quit=self.bye, default_menu_index=1, diff --git a/memorytools/plugins/__init__.py b/memorytools/plugins/__init__.py index 9a83a08..5c5048c 100644 --- a/memorytools/plugins/__init__.py +++ b/memorytools/plugins/__init__.py @@ -1,15 +1,15 @@ +from importlib import import_module from pathlib import Path from .base import BasePlugin, change_config +plugin_path = Path() / "plugins" -# plugin_path = Path() / "plugins" -# -# all_plugins = [] -# for d in plugin_path.iterdir(): -# if d.is_dir() and d.name != "__pycache__": -# all_plugins.append(__import__("plugins."+d.name)) - - -# print(all_plugins) - +plugin_list = [] +for d in plugin_path.iterdir(): + if d.is_dir() and d.name != "__pycache__": + plugin = import_module("plugins." + d.name).plugin + plugin_list.append(plugin) + print(plugin.__module__) +# print(plugin_list) +# all_plugins = [p.plugin for p in all_plugins] diff --git a/memorytools/plugins/alert/__init__.py b/memorytools/plugins/alert/__init__.py index cdebfc6..97c1058 100644 --- a/memorytools/plugins/alert/__init__.py +++ b/memorytools/plugins/alert/__init__.py @@ -1,3 +1,3 @@ from .alert import Alert -__all__ = [Alert] +plugin = Alert diff --git a/memorytools/plugins/alert/alert.py b/memorytools/plugins/alert/alert.py index 2ccaf90..2a03553 100644 --- a/memorytools/plugins/alert/alert.py +++ b/memorytools/plugins/alert/alert.py @@ -60,3 +60,4 @@ def start(self): alert_message = TEXT.alert % self.alert_time LabelBox('危险警报').show(alert_message, '等你想要继续工作了再点我') self.start_time = time() + diff --git a/memorytools/plugins/copytrans/__init__.py b/memorytools/plugins/copytrans/__init__.py index 041973a..d84c705 100644 --- a/memorytools/plugins/copytrans/__init__.py +++ b/memorytools/plugins/copytrans/__init__.py @@ -1,3 +1,3 @@ from .copytrans import CopyTrans -__all__ = [CopyTrans] +plugin = CopyTrans diff --git a/memorytools/plugins/ocr/__init__.py b/memorytools/plugins/ocr/__init__.py index 0072094..d6f07ef 100644 --- a/memorytools/plugins/ocr/__init__.py +++ b/memorytools/plugins/ocr/__init__.py @@ -2,4 +2,4 @@ from .xueersiOCR import LatexOCR from .ocr import OCR -__all__ = [BaiduOCR, LatexOCR, OCR] +plugin = OCR From bfb08b22b63dc62134f27975e3930d2bdea7fe85 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Sat, 10 Oct 2020 12:32:23 +0800 Subject: [PATCH 14/28] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- memorytools/globals.py | 2 + memorytools/memorytools.py | 13 +++++-- .../{copytrans => 01_copytrans}/__init__.py | 0 .../{copytrans => 01_copytrans}/config.json | 2 +- .../{copytrans => 01_copytrans}/copytrans.py | 21 +++++++++- .../plugins/{ocr => 02_ocr}/__init__.py | 0 .../plugins/{ocr => 02_ocr}/baiduOCR.py | 0 .../plugins/{ocr => 02_ocr}/config.json | 4 +- memorytools/plugins/{ocr => 02_ocr}/ocr.py | 11 ++++++ .../plugins/{ocr => 02_ocr}/xueersiOCR.py | 0 .../plugins/{alert => 03_alert}/__init__.py | 0 .../plugins/{alert => 03_alert}/alert.py | 8 +++- .../plugins/{alert => 03_alert}/config.json | 2 +- memorytools/plugins/__init__.py | 14 +++---- memorytools/plugins/base.py | 13 +++---- memorytools/tools/logger.py | 38 +++++++++++++++++++ 16 files changed, 103 insertions(+), 25 deletions(-) rename memorytools/plugins/{copytrans => 01_copytrans}/__init__.py (100%) rename memorytools/plugins/{copytrans => 01_copytrans}/config.json (81%) rename memorytools/plugins/{copytrans => 01_copytrans}/copytrans.py (82%) rename memorytools/plugins/{ocr => 02_ocr}/__init__.py (100%) rename memorytools/plugins/{ocr => 02_ocr}/baiduOCR.py (100%) rename memorytools/plugins/{ocr => 02_ocr}/config.json (68%) rename memorytools/plugins/{ocr => 02_ocr}/ocr.py (82%) rename memorytools/plugins/{ocr => 02_ocr}/xueersiOCR.py (100%) rename memorytools/plugins/{alert => 03_alert}/__init__.py (100%) rename memorytools/plugins/{alert => 03_alert}/alert.py (81%) rename memorytools/plugins/{alert => 03_alert}/config.json (54%) create mode 100644 memorytools/tools/logger.py diff --git a/memorytools/globals.py b/memorytools/globals.py index e190186..9630d3f 100644 --- a/memorytools/globals.py +++ b/memorytools/globals.py @@ -2,6 +2,7 @@ from easydict import EasyDict from pathlib import Path from base64 import b64decode +from tools.logger import logger icon_bs64 = { "icon.ico": "AAABAAEAgIAAAAEAIAAoCAEAFgAAACgAAACAAAAAAAEAAAEAIAAAAAAAAAABABILAAASCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARZLjCkiX5yZPnuxCXrD2ZmS3+ntjtfmMZrr8q2i8/btnuvzCZrr72Ge7/Otou/30aLz9+Wm9/v1qvv7+ar7+/mu///9rv///ar7+/mm9/v1pvf37aLz9+Gi7/O5nuvzhZrr7zmm9/b5nu/y0Zrr8oGa5/IRitPh0VKTuVEyc6jVJmOgZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFkuQiRZLkT0WT5HlEk+ShRZPkxkST5OhFk+X+RZPl/0ua6f9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2q+/v9GlOX/RZPl/0WT5f9GlOXzRZPl0kST5a1Ek+SFRJLkW0SS5C5Ek+QFAAAAAAAAAAAAAAAAAAAAAMCJaB7IiF+HyIhfzsmIYPHIiWDxyIhfzsiIX4fIiF8eAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEk+QRRJLkTUST5IdFkuW9RZLk70WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/UKDt/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///ar3+/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5fhFk+TJTJLdk2KQxlm2inF5yYlf98mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mIYPbIh2BzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJLjA0WT5D1Ek+SHRJLlzUWT5f1Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9brPT/a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///Spnp/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/jY2b/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/IiGCKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAESS5AFFkuUiRZHlR0WS5V9FkuRsRZLkbkSS5GREk+RORJPkLUST5AYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJLkPESS5ZhFkuXqRZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RpTl/2e7/P9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9YqfL/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/26Pu//IiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP7IiV9OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJPlF0ST5GtEk+W0RJPl70WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl+USS5cVEk+V+RZLkKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEkuQMRJPkb0WS5NlFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Wp/D/a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2m8/f9Jl+f/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9IkuH/t4px/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mIYNYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJLkNkSS5axEk+X6RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X+RJPlxkSR5FNFkeMBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEkeQKRJLle0WS5O1Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/S5rp/2m9/f9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2Gz+P9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/32OrP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8CJaDMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJLjH0WS5K1Fk+X+RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0SS5cxFk+Q4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJLlT0ST5eJFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0mY6P9lufv/a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///12u9f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Lkt7/vYlr/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/oouGjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEST5GBFk+XyRZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5fxFkuSIRZLkBAAAAAAAAAAARJLkBkSS5JhFk+X+RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Pnuv/Z7r8/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///12v9v9GlOX/RZPl/0WT5f9Fk+X/RZPl/4aOov/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP+FjqT/TpLbs0uR3BEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAESS5AJEkuSTRZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9FkuW9RZHkEEWS5QlFkuS7RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Nnev/XrD2/2q+/v9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2O1+f9Kmej/RZPl/0WT5f9Qktn/wolm/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/32OrP9Fk+X/RZPl2kSS5CEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEkuQCRJLkpEWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9FkuXORZLlsEWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Onuv/U6Pu/1eo8f9dr/X/Zrr8/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2m9/f9Wp/D/RpTl/5CNmP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/YpDH/0WT5f9Fk+X/RZPl4ESS5BoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEST5ZFFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/1+y9/9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9ysuf/xYlj/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/7aKcv9FkuT/RZPl/0WT5f9Fk+X/RZLkzESS5AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEk+RbRZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/Xa71/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///6ecmP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/do+y/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RJLklwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJLlGUWT5e9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9YqfL/a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///98tOH/yIlh/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/7KKdv9GkuP/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X+RJLkRgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFkuWgRZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f5Ek+TaRJPlrUST5ZVFk+WSRJLkpUST5MxFk+T6RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/1Oj7/9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///66YjP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/bY+8/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+XbRJLkBgAAAAAAAAAAAAAAAAAAAAAAAAAARJLlJUWT5fxFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WS5epEk+V8RJPlHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEST4xBEk+RlRZPl2EWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/TZzq/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///+Dsdb/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/6qLfv9Fk+T/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Ek+VuAAAAAAAAAAAAAAAAAAAAAAAAAABEkuWQRZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Ek+SfRJLlDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEkuQERJPkeUWT5ftFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9GlOX/ar7+/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a77+/7SUgv/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/IiWD/ZJDF/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0ST5eNEk+UFAAAAAAAAAAAAAAAARJPkA0SS5elFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RJLkfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJLlS0WT5fhFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9itfn/a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///+Jrcr/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/6CMiP9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5VgAAAAAAAAAAAAAAABDk+U5RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0SS5KUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJPlYkWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/1ip8v9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///bL78/7qReP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/HiWH/W5HO/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RJLkugAAAAAAAAAAAAAAAEST5XdFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Ek+TzQ5HjFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJLluEWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/TJvq/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///+Qqb//yYlg/8mJYP/JiWD/yIlg/7mKcP+si3z/q4t9/7SKdP/EiWX/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/5eMkv9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X7RZPkEwAAAAAAAAAARJLkpUWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0ST5ZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEkuQ4RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/Zbj7/2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///brz4/7+OcP/JiWD/wYln/3+Oqf9Qktn/RZPl/0WT5f9Fk+X/RZPl/0WS5P9ZkdD/eo6v/6OLhv/GiWL/yYlg/8mJYP/FiWT/VJHV/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+VaAAAAAAAAAABEkuTGRZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RJPkVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAESS5SZFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Wp/H/a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///+XpbT/yYlg/8eJYf9gkcn/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/1OR1v+NjZv/xIlk/42Nm/9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0ST5ZoAAAAAAAAAAEWS5dtFk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9EkuQrAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARJPkWEWT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0WT5f9Fk+X/RZPl/0iW5/9pvf7/a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///a7///2u///9rv///cbvz/8OM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+v9Wpvr/Vqb6/1am+v9Wpvr/os78//3+/v/////////////////////////////////////////////////////////////////RnHn/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/IiF8sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADJiGCPyYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/ny7n/////////////////////////////////////////////////9ff6/9vk7f/v8/f//////+Tx/v9jrPr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9LluX/MW+w/yJZk/8iWZL/IlmS/yJZkv8iWZL/IlmS/yJZkv8iWZL/IlmS/yJZkv8jW5X/OnzC/1Sj9/9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/6XQ/P////////////z9/v/f5+//5Ovy//7+/v///////////////////////////////////////////9Off//JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8iJXzQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMmJYJPJiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/+jMu///////////////////////////////////////9/n7/36dv/8oXJT/IliS/yNZkv9ojbT/6/D1/9Dm/f9Wpvr/Vqb6/1am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/v9HdKT/IliS/yJYkv8iWJL/IliS/yJYkv8iWJL/bpG3////////////////////////////9enh/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yIhf6wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMiIXy3JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8qMZf/+/fz/////////////////////////////////iKXE/yJYkv8iWJL/IliS/yJYkv8iWJL/Y4my//3+/v//////5PH+/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/mcn8/////////////////8nW5P8oXJX/IliS/yJYkv8iWJL/IliS/zVmm//j6vH////////////////////////////s1cf/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiF/JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAx4dgCcmJX/3JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg//Xq4v/////////////////////////////////+/v7/qL3U/0h1pf8nXJT/Pm2g/5Ksyf/5+/z////////////m8v7/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v+ayvz//////////////////////9Lc6P9fhrD/LF+W/zBjmf9vkrj/4+rx/////////////////////////////////+G+p//JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8iIX6YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyYlf3MmJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/6c++/////////////////////////////////////////////////////////////////////////////////9rr/f9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/47D+///////////////////////////////////////////////////////////////////////////////////////1KKD/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yIlfegAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIiF+ryYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/ar5T/////////////////////////////////////////////////////////////////////////////////vdz9/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/cbT6//////////////////////////////////////////////////////////////////////////////////v39P/JimL/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/IiV9LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMiIX3LJiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8yQaf/9/Pv///////////////////////////////////////////////////////////////////////////+Rxfv/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/7fX+////////////////////////////////////////////////////////////////////////////7NbI/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/siIXxMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyIhfNsmJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/+7bz///////////////////////////////////////////////////////////////////////9fn+/12q+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v+x1vz////////////////////////////////////////////////////////////////////////////ar5P/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/IiGDWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIiV4DyYhg7smJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/27CV//////////////////////////////////////////////////////////////////////+s0/z/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/2ev+v/4+/7/////////////////////////////////////////////////////////////////+/bz/8qMZP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8iIX5IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIiV+pyYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/Ki2P/+vTw////////////////////////////////////////////////////////////5/L+/12p+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/6PO/P/////////////////////////////////////////////////////////////////nyrn/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/x4hgSgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMiJX1nJiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/JiWD/yYlg/8mJYP/jwq3///////////////////////////////////////////////////////b6/v92t/v/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am+v9Wpvr/Vqb6/1am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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEST5VdFk+XvRZPl/0WT5f9Fk+X/R5XmagAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEST5ANEkuSsRZPl70SS5JdDk+UWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAESS5RlFkuWaRZPk8ESS5KVEkuQBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////gAAAAD//////////////4AAAAAAAeAf//////////AAAAAAAAAAD/////////8AAAAAAAAAAAf///+AH//8AAAAAAAAAAAD///8AAP/4AAAAAAAAAAAA///8AAAf4AAAAAAAAAAAAH//8AAAD8AAAAAAAAAAAAB//+AAAAMAAAAAAAAAAAAAH/+AAAAAAAAAAAAAAAAAAA//AAAAAAAAAAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAA/4AAAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAAAAB/AAAAAAAAAAAAAAAAAAAAPgAB+AAAAAAAAAAAAAAAAD4AB/4AAAAAAAAAAAAAAAAcAB//gAAAAAAAAAAAAAAAHAA//8AAAAAAAAAAAAAAABwAP//gAAAAAAAAAAAAAAAMAH//4AAAAAAAAAAAAAAADAB//+AAAAAAAAAAAAAAAAwAf//gAAAAAAAAAAAAAAAMAH//4AAAAAAAAAAAAAAABAB//+AAAAAAAAAAAAAAAAQAf//gAAAAAAAAAAAAAAAEAH//4AAAAAAAAAAAAAAABAB//+AAAAAAAAAAAAAAAAQAf//gAAAAAAAAAAAAAAAEAD//4AAAAAAAAAAAAAAABAA//+AAAAAAAAAAAAAAAAYAf//gAAAAAAAAAAAAAAAGAH//4AAAAAAAAAAAAAAABwD//+AAAAAAAAAAAAAAAAeB///gAAAAAAAAAAAAAAAH////4AAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAP////8AAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAP////+AAAAAAAAAAAAAAAH/////gAAAAAAAAAAAAAAB/////4AAAAAAAAAAAAAAAf/////AAAAAAAAAAAAAAAH/////wAAAAAAAAAAAAAAD/////8AAAAAAAAAAAAAAA//////gAAAAAAAAAAAAAAP/////4AAAAAAAAAAAAAAH/////+AAAAAAAAAAAAAAB//////wAAAAAAAAAAAAAAf/////8AAAAAAAAAAAAAAP//////gAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAB//////8AAAAAAAAAAAAAAf/////+AAAAAAAAAAAAAAP//////gAAAAAAAAAAAAAD//////wAAAAAAAAAAAAAA//////8AAAAAAAAAAAAAAf//////AAAAAAAAAAAAAAH//////gAAAAAAAAAAAAAB//////4AAAAAAAAAAAAAAP/////+AAAAAAAAAAAAAAD//////AAAAAAAAAAAAAAA//////wAAAAAAAAAAAAAAP/////8AAAAAAAAAAAAAAB//////AAAAAAAAAAAAAAAf/////wAAAAAAAAAAAAAAH/////4AAAAAAAAAAAAAAB/////+AAAAAAAAAAAAAAAf/////gAAAAAAAAAAAAAAH/////4AAAAAAAAAAAAAAA/////+AAAAAAAAAAAAAAAP/////gAAAAAAAAAAAAAAD/////4AAAAAAAAAAAAAAA/////+AAAAAAAAAAAAAAAP/////gAAAAAAAAAAAAAAD/////4AAAAAAAAAAAAAAA/////+AAAAAAAAAAAAAAAP/////gAAAAAAAAAAAAAAD/////4AAAAAAAAAAAAAAB/////+AAAAAAAAAAAAAAAf/////gAAAAAAAAAAAAAAH/////8AAAAAAAAAAAAAAB//////AAAAAAAAAAAAAAAf/////wAAAAAAAAAAAAAAH/////8AAAAAAAAAAAAAAD//////AAAAAAAAAAAAAAA//////4AAAAAAAAAAAAAAP/////+AAAAAAAAAAAAAAD//////gAAAAAAAAAAAAAB//////8AAAAAAAAAAAAAAf//////AAAAAAAAAAAAAAH//////wAAAAAAAAAAAAAD//////+AAAAAAAAAAAAAA///////gAAAAAAAAAAAAAf//////8AAAAAAAAAAAAAH///////AAAAAAAAAAAAAD///////4AAAAAAAAAAAAA////////AAAAAAAAAAAAAf///////wAAAAAAAAAAAAP///////+AAAAAAAAAAAAD////////wAAAAAAAAAAAB////////8AAAAAAAAAAAA/////////gAAAAAAAAAAAP////////8AAAAAAAAAAAH/////////gAAAAAAAAAAD/////////8AAAAAAAAAAB//////////gAAAAAAAAAA//////////8AAAAAAAAAAf//////////gAAAAAAAAAP//////////4AAAAAAAAAH//////////+AAAAAAAAAD///////////gAAAAAAAAA///////////4AAAAAAAAAP//////////+AAAAAAAAAD///////////gAAAAAAAAA///////////4AAAAAAAAAP///////////AAAAAAAAAH///////////wAAAAAAAAB///////////8AAcAAAMAAf///////////AAP/AD/gAH///////////wAH////8AB///////////+AD/////gA////////////gB/////8AP///////////4A//////gD////////////A//////+B////////////wf//////wf///8=", @@ -35,6 +36,7 @@ def get_icon(): for name, ico in icon_bs64.items(): name = PATH.icon / name if not name.exists(): + logger.info("[globals] 创建图标: %s" % name) name.write_bytes(b64decode(ico)) icons = EasyDict() diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index cca5240..eb0fa45 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -2,6 +2,7 @@ from time import sleep from globals import TEXT, ICON from plugins import plugin_list +from tools.logger import logger from tools.systray import SysTrayIcon @@ -37,7 +38,7 @@ def create_menu(self): def refresh_menu(self): """ - 刷新菜单 + 每次用户点击托盘菜单以后,都要重新刷新菜单。 """ self.systray.refreshMenu(self.create_menu()) @@ -52,17 +53,21 @@ def bye(self, s: SysTrayIcon): 退出程序 """ self.end = True - print('bye') + logger.info("[MemoryTools] 退出程序") def run(self): """ - 启动主程序 + 启动主程序,由于tkinter组件不能在线程中结束,因此在主线程中调用 """ self.systray.start() + logger.info("[Memory Tools] 程序开始运行...") while not self.end: sleep(0.1) for plugin in self.plugins: - plugin.start() + try: + plugin.start() + except Exception as e: + logger.error(e) if __name__ == '__main__': diff --git a/memorytools/plugins/copytrans/__init__.py b/memorytools/plugins/01_copytrans/__init__.py similarity index 100% rename from memorytools/plugins/copytrans/__init__.py rename to memorytools/plugins/01_copytrans/__init__.py diff --git a/memorytools/plugins/copytrans/config.json b/memorytools/plugins/01_copytrans/config.json similarity index 81% rename from memorytools/plugins/copytrans/config.json rename to memorytools/plugins/01_copytrans/config.json index d1fda99..25b5e1e 100644 --- a/memorytools/plugins/copytrans/config.json +++ b/memorytools/plugins/01_copytrans/config.json @@ -1,5 +1,5 @@ { - "is_trans": true, + "is_trans": false, "newline": false, "strict": false, "mode": "both", diff --git a/memorytools/plugins/copytrans/copytrans.py b/memorytools/plugins/01_copytrans/copytrans.py similarity index 82% rename from memorytools/plugins/copytrans/copytrans.py rename to memorytools/plugins/01_copytrans/copytrans.py index 2c7314d..e0e191c 100644 --- a/memorytools/plugins/copytrans/copytrans.py +++ b/memorytools/plugins/01_copytrans/copytrans.py @@ -3,6 +3,7 @@ from tools.boxes import TextTextBox from googletransx import Translator from tools.utils import is_check, is_pick, judge_language, paste_clip +from tools.logger import logger from requests.exceptions import ConnectionError from plugins import BasePlugin, change_config from globals import ICON @@ -30,28 +31,43 @@ def create_menu(self) -> tuple: @change_config def pause_trans(self, s): self.is_trans = not self.is_trans + if self.is_trans: + logger.info("[复制翻译] 开启复制翻译") + else: + logger.info("[复制翻译] 关闭复制翻译") @change_config def en2zh_mode(self, s): self.mode = 'en2zh' self.src, self.dest = 'en', 'zh-cn' + logger.info("[复制翻译] 切换翻译模式为: 英译中") @change_config def zh2en_mode(self, s): self.mode = 'zh2en' self.src, self.dest = 'zh-cn', 'en' + logger.info("[复制翻译] 切换翻译模式为: 中译英") @change_config def both_mode(self, s): self.mode = 'both' + logger.info("[复制翻译] 切换翻译模式为: 中英互译") @change_config def turn_strict(self, s): self.strict = not self.strict + if self.strict: + logger.info("[复制翻译] 开启严格模式") + else: + logger.info("[复制翻译] 关闭严格模式") @change_config def turn_newline(self, s): self.newline = not self.newline + if not self.newline: + logger.info("[复制翻译] 开启去除换行") + else: + logger.info("[复制翻译] 关闭去除换行") def remove_newline(self, source): if not self.newline: @@ -74,7 +90,8 @@ def pre_process(self, source): return None text = source.strip() src_language, score = judge_language(text) - print('检测为:%s, %s. 目标语言为:%s' % (src_language, score, self.dest)) + msg = '检测为: %s, %s. 目标语言为: %s' % (src_language, score, self.dest) + logger.info("[复制翻译] " + msg) if not src_language: self.last = source return None @@ -116,7 +133,7 @@ def trans(self, source: str): if text == sentence: self.last = source - print('译文与原文一致,因此不显示。') + logger.info('[复制翻译] 译文与原文一致,因此不显示。') return None # print("%s\n%s\n" % (sentence, text)) TextTextBox('翻译结果').show(sentence, text) diff --git a/memorytools/plugins/ocr/__init__.py b/memorytools/plugins/02_ocr/__init__.py similarity index 100% rename from memorytools/plugins/ocr/__init__.py rename to memorytools/plugins/02_ocr/__init__.py diff --git a/memorytools/plugins/ocr/baiduOCR.py b/memorytools/plugins/02_ocr/baiduOCR.py similarity index 100% rename from memorytools/plugins/ocr/baiduOCR.py rename to memorytools/plugins/02_ocr/baiduOCR.py diff --git a/memorytools/plugins/ocr/config.json b/memorytools/plugins/02_ocr/config.json similarity index 68% rename from memorytools/plugins/ocr/config.json rename to memorytools/plugins/02_ocr/config.json index 05abadf..0309782 100644 --- a/memorytools/plugins/ocr/config.json +++ b/memorytools/plugins/02_ocr/config.json @@ -1,5 +1,5 @@ { "is_ocr": false, "newline": false, - "mode": "text" -} + "mode": "math" +} \ No newline at end of file diff --git a/memorytools/plugins/ocr/ocr.py b/memorytools/plugins/02_ocr/ocr.py similarity index 82% rename from memorytools/plugins/ocr/ocr.py rename to memorytools/plugins/02_ocr/ocr.py index 1935e92..7f16475 100644 --- a/memorytools/plugins/ocr/ocr.py +++ b/memorytools/plugins/02_ocr/ocr.py @@ -4,6 +4,7 @@ from . import LatexOCR from PIL import Image, ImageGrab, ImageDraw from tools.boxes import ImageTextBox +from tools.logger import logger from globals import BAIDU_ACCOUNTS, XUEERSI_ACCOUNTS, ICON from tools.utils import is_check, is_pick, get_rect, Color, copy_clip from plugins import BasePlugin, change_config @@ -29,18 +30,28 @@ def create_menu(self) -> tuple: @change_config def pause_ocr(self, s): self.is_ocr = not self.is_ocr + if self.is_ocr: + logger.info("[OCR识别] 开启OCR识别") + else: + logger.info("[OCR识别] 关闭OCR识别") @change_config def text_mode(self, s): self.mode = 'text' + logger.info("[OCR识别] 切换OCR识别模式为: 文本") @change_config def math_mode(self, s): self.mode = 'math' + logger.info("[OCR识别] 切换OCR识别模式为: 公式") @change_config def turn_newline(self, s): self.newline = not self.newline + if not self.newline: + logger.info("[OCR识别] 开启去除换行") + else: + logger.info("[OCR识别] 关闭去除换行") def start(self): if not self.is_ocr: diff --git a/memorytools/plugins/ocr/xueersiOCR.py b/memorytools/plugins/02_ocr/xueersiOCR.py similarity index 100% rename from memorytools/plugins/ocr/xueersiOCR.py rename to memorytools/plugins/02_ocr/xueersiOCR.py diff --git a/memorytools/plugins/alert/__init__.py b/memorytools/plugins/03_alert/__init__.py similarity index 100% rename from memorytools/plugins/alert/__init__.py rename to memorytools/plugins/03_alert/__init__.py diff --git a/memorytools/plugins/alert/alert.py b/memorytools/plugins/03_alert/alert.py similarity index 81% rename from memorytools/plugins/alert/alert.py rename to memorytools/plugins/03_alert/alert.py index 2a03553..1dec012 100644 --- a/memorytools/plugins/alert/alert.py +++ b/memorytools/plugins/03_alert/alert.py @@ -3,6 +3,7 @@ from tools.boxes import LabelBox from globals import TEXT, ICON from tools.utils import is_check, is_pick +from tools.logger import logger from plugins import BasePlugin, change_config from pathlib import Path @@ -29,25 +30,30 @@ def pause_alert(self, s): self.is_alert = not self.is_alert if self.is_alert: self.start_time = time() + logger.info("[休息提醒] 开启休息提醒") else: - print("虽然你关掉了休息提醒,但还是要注意身体!") + logger.info("[休息提醒] 关闭休息提醒") # LabelBox().show("虽然你关掉了休息提醒,但还是要注意身体!", "确定") @change_config def set_alert_time_30(self, s): self.alert_time = 30 + logger.info("[休息提醒] 将休息提醒时间设置为 30 分钟.") @change_config def set_alert_time_60(self, s): self.alert_time = 60 + logger.info("[休息提醒] 将休息提醒时间设置为 60 分钟.") @change_config def set_alert_time_90(self, s): self.alert_time = 90 + logger.info("[休息提醒] 将休息提醒时间设置为 90 分钟.") @change_config def set_alert_time_120(self, s): self.alert_time = 120 + logger.info("[休息提醒] 将休息提醒时间设置为 120 分钟.") def alert(self): minute = (time() - self.start_time) / 60 # 分钟数 diff --git a/memorytools/plugins/alert/config.json b/memorytools/plugins/03_alert/config.json similarity index 54% rename from memorytools/plugins/alert/config.json rename to memorytools/plugins/03_alert/config.json index 664824e..ffd227f 100644 --- a/memorytools/plugins/alert/config.json +++ b/memorytools/plugins/03_alert/config.json @@ -1,4 +1,4 @@ { "is_alert": true, - "alert_time": 90 + "alert_time": 30 } \ No newline at end of file diff --git a/memorytools/plugins/__init__.py b/memorytools/plugins/__init__.py index 5c5048c..93cb069 100644 --- a/memorytools/plugins/__init__.py +++ b/memorytools/plugins/__init__.py @@ -1,15 +1,15 @@ from importlib import import_module from pathlib import Path +from tools.logger import logger from .base import BasePlugin, change_config -plugin_path = Path() / "plugins" +# 插件包所在的目录 +plugin_path = Path(__file__).parent +# 加载所有的插件包 plugin_list = [] for d in plugin_path.iterdir(): if d.is_dir() and d.name != "__pycache__": - plugin = import_module("plugins." + d.name).plugin - plugin_list.append(plugin) - print(plugin.__module__) - -# print(plugin_list) -# all_plugins = [p.plugin for p in all_plugins] + module = import_module("plugins." + d.name) + plugin_list.append(module.plugin) + logger.info("[plugin init] 发现插件包: "+module.__name__) diff --git a/memorytools/plugins/base.py b/memorytools/plugins/base.py index 162da57..f7c8b36 100644 --- a/memorytools/plugins/base.py +++ b/memorytools/plugins/base.py @@ -1,5 +1,6 @@ import json from easydict import EasyDict +from tools.logger import logger def change_config(set_attr): @@ -25,6 +26,7 @@ def __init__(self, name: str, root, icon: str, config_path): self.icon = icon self.config_path = config_path self.config = self.init_config() + logger.info("[plugin base] 初始化插件: " + self.name) def init_config(self): config = self.config_path.read_text(encoding="utf-8") @@ -42,14 +44,11 @@ def save_config(self): data = json.dumps(self.config, indent=4, ensure_ascii=False) self.config_path.write_text(data, encoding="utf-8") - # def create_default_config(self) -> EasyDict: - # raise NotImplementedError - - def create_menu(self) -> tuple: - return () - def init_menu(self) -> tuple: return self.name, self.icon, self.create_menu(), True - def start(self): + def create_menu(self) -> tuple: + raise NotImplementedError + + def start(self) -> None: raise NotImplementedError diff --git a/memorytools/tools/logger.py b/memorytools/tools/logger.py new file mode 100644 index 0000000..12ca526 --- /dev/null +++ b/memorytools/tools/logger.py @@ -0,0 +1,38 @@ +import logging +import logging.handlers +from sys import stdout + + +class Logger(object): + def __init__(self, log_level=logging.INFO, log_file=None): + """ + 指定日志级别,以及是否将日志存入到指定的文件中 + """ + formatter = logging.Formatter("[%(asctime)s %(levelname)s] - %(message)s") + self.logger = logging.getLogger() + self.logger.setLevel(log_level) + + ch = logging.StreamHandler(stdout) + ch.setLevel(log_level) + ch.setFormatter(formatter) + self.logger.addHandler(ch) + + if log_file: + fh = logging.handlers.TimedRotatingFileHandler(log_file, when='D', interval=1, backupCount=30) + fh.setLevel(log_level) + fh.setFormatter(formatter) + self.logger.addHandler(fh) + + def get_logger(self): + return self.logger + + +logger = Logger(log_file="log/memorytools.log").get_logger() + +if __name__ == '__main__': + # logger = Logger().get_logger() + logger.debug("debug msg") + logger.info('info msg') + logger.warning('warn msg') + logger.error('error msg') + logger.critical('critical msg') From 63455ce5a4f23a0f5c9a8d26d2cd24095554f229 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Sat, 10 Oct 2020 12:52:57 +0800 Subject: [PATCH 15/28] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- memorytools/log/memorytools.log | 67 ++++++++++++++++++++++++ memorytools/memorytools.py | 15 +++--- memorytools/plugins/02_ocr/config.json | 2 +- memorytools/plugins/03_alert/config.json | 4 +- memorytools/plugins/base.py | 32 +++++++++++ 5 files changed, 111 insertions(+), 9 deletions(-) create mode 100644 memorytools/log/memorytools.log diff --git a/memorytools/log/memorytools.log b/memorytools/log/memorytools.log new file mode 100644 index 0000000..f0b33c5 --- /dev/null +++ b/memorytools/log/memorytools.log @@ -0,0 +1,67 @@ +[2020-10-10 12:33:22,347 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 12:33:22,363 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 12:33:22,366 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 12:33:22,374 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 12:33:22,376 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 12:33:22,376 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 12:33:22,378 INFO] - [Memory Tools] ʼ... +[2020-10-10 12:33:26,327 INFO] - [OCRʶ] OCRʶ +[2020-10-10 12:33:30,753 INFO] - [MemoryTools] ˳ +[2020-10-10 12:33:41,390 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 12:33:41,405 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 12:33:41,407 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 12:33:41,415 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 12:33:41,416 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 12:33:41,417 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 12:33:41,418 INFO] - [Memory Tools] ʼ... +[2020-10-10 12:36:36,904 INFO] - [MemoryTools] ˳ +[2020-10-10 12:36:38,764 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 12:36:38,779 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 12:36:38,781 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 12:36:38,782 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 12:36:38,784 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 12:36:38,784 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 12:36:38,785 INFO] - [Memory Tools] ʼ... +[2020-10-10 12:36:46,056 INFO] - [MemoryTools] ˳ +[2020-10-10 12:36:54,620 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 12:36:54,635 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 12:36:54,638 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 12:36:54,639 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 12:36:54,641 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 12:36:54,641 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 12:36:54,642 INFO] - [Memory Tools] ʼ... +[2020-10-10 12:37:04,498 INFO] - [MemoryTools] ˳ + + +[2020-10-10 12:37:31,032 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 12:37:31,046 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 12:37:31,048 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 12:37:31,049 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 12:37:31,051 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 12:37:31,051 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 12:37:31,053 INFO] - [Memory Tools] ʼ... +[2020-10-10 12:37:40,888 INFO] - [MemoryTools] ˳ + + +[2020-10-10 12:38:55,575 INFO] - [MemoryTools] +[2020-10-10 12:38:55,787 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 12:38:55,801 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 12:38:55,804 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 12:38:55,805 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 12:38:55,806 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 12:38:55,807 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 12:38:55,808 INFO] - [Memory Tools] ʼ... +[2020-10-10 12:39:01,212 INFO] - [MemoryTools] ˳ + +[2020-10-10 12:39:11,268 INFO] - [MemoryTools] +[2020-10-10 12:39:11,481 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 12:39:11,497 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 12:39:11,500 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 12:39:11,501 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 12:39:11,503 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 12:39:11,503 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 12:39:11,505 INFO] - [MemoryTools] ʼ... +[2020-10-10 12:39:19,501 INFO] - [Ϣ] رϢ +[2020-10-10 12:39:23,637 INFO] - [Ϣ] ϢʱΪ 60 . +[2020-10-10 12:39:27,133 INFO] - [MemoryTools] ˳ + diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index eb0fa45..b1e931b 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -1,9 +1,12 @@ -import webbrowser +from webbrowser import open as open_web from time import sleep -from globals import TEXT, ICON -from plugins import plugin_list from tools.logger import logger + +logger.info("[MemoryTools] 启动程序") + from tools.systray import SysTrayIcon +from globals import TEXT, ICON +from plugins import plugin_list class MemoryTool(object): @@ -46,21 +49,21 @@ def about(self, s: SysTrayIcon): """ 菜单中的 关于 选项 """ - webbrowser.open("https://github.com/MemoryD/MemoryTools") + open_web("https://github.com/MemoryD/MemoryTools") def bye(self, s: SysTrayIcon): """ 退出程序 """ self.end = True - logger.info("[MemoryTools] 退出程序") + logger.info("[MemoryTools] 退出程序\n") def run(self): """ 启动主程序,由于tkinter组件不能在线程中结束,因此在主线程中调用 """ self.systray.start() - logger.info("[Memory Tools] 程序开始运行...") + logger.info("[MemoryTools] 插件开始运行...") while not self.end: sleep(0.1) for plugin in self.plugins: diff --git a/memorytools/plugins/02_ocr/config.json b/memorytools/plugins/02_ocr/config.json index 0309782..0fd8c3a 100644 --- a/memorytools/plugins/02_ocr/config.json +++ b/memorytools/plugins/02_ocr/config.json @@ -1,5 +1,5 @@ { - "is_ocr": false, + "is_ocr": true, "newline": false, "mode": "math" } \ No newline at end of file diff --git a/memorytools/plugins/03_alert/config.json b/memorytools/plugins/03_alert/config.json index ffd227f..76876d9 100644 --- a/memorytools/plugins/03_alert/config.json +++ b/memorytools/plugins/03_alert/config.json @@ -1,4 +1,4 @@ { - "is_alert": true, - "alert_time": 30 + "is_alert": false, + "alert_time": 60 } \ No newline at end of file diff --git a/memorytools/plugins/base.py b/memorytools/plugins/base.py index f7c8b36..729113c 100644 --- a/memorytools/plugins/base.py +++ b/memorytools/plugins/base.py @@ -20,7 +20,23 @@ def wrapper(plugin, s): class BasePlugin(object): + """ + 所有插件的基类,提供插件的统一运行框架。 + 每个插件都以一个模块的形式存在,假设在一个插件名为 test,则可以: + 1. 创建一个包为 plugins/test (文件夹名字随意) + 2. 包内至少 3 个文件: + 2.1 __init__.py: 必须包含一个变量 plugin, 指向一个 BasePlugin 的子类 + 2.2 test.py(文件名随意):插件的主要运行代码,其中有一个类必须继承 BasePlugin,并写到 __init__.py 中 + 2.3 config.json:托盘菜单配置文件,里面的属性会被绑定到 BasePlugin 子类中 + 具体可以参阅plugins文件夹下面的几个插件。 + """ def __init__(self, name: str, root, icon: str, config_path): + """ + :param name: 该插件的名字,会显示在托盘菜单中 + :param root: MemoryTools类,会由主程序自动传入 + :param icon: 图标的路径 + :param config_path: 配置文件的路径 + """ self.name = name self.root = root self.icon = icon @@ -29,6 +45,9 @@ def __init__(self, name: str, root, icon: str, config_path): logger.info("[plugin base] 初始化插件: " + self.name) def init_config(self): + """ + 读取目录下的配置文件,并将属性绑定到类中 + """ config = self.config_path.read_text(encoding="utf-8") config = EasyDict(json.loads(config)) @@ -38,6 +57,10 @@ def init_config(self): return config def save_config(self): + """ + 从类中获取配置的属性,并保存到文件中 + :return: + """ for attr in self.config: self.config[attr] = self.__getattribute__(attr) @@ -45,10 +68,19 @@ def save_config(self): self.config_path.write_text(data, encoding="utf-8") def init_menu(self) -> tuple: + """ + 入口菜单项 + """ return self.name, self.icon, self.create_menu(), True def create_menu(self) -> tuple: + """ + 子菜单,格式可以参考 MemoryTools 类中的 create_menu 方法 + """ raise NotImplementedError def start(self) -> None: + """ + 主要运行的函数,会被主程序重复调用 + """ raise NotImplementedError From 1ea76cc676b2c7433545f9a5076c348e5f445c75 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Sat, 10 Oct 2020 16:51:21 +0800 Subject: [PATCH 16/28] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E5=BC=B9=E5=87=BA?= =?UTF-8?q?=E6=A1=86=E7=9A=84=E7=BB=84=E7=BB=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- memorytools/log/memorytools.log | 326 ++++++++++++++---- memorytools/plugins/01_copytrans/__init__.py | 2 + memorytools/plugins/01_copytrans/config.json | 2 +- memorytools/plugins/01_copytrans/copytrans.py | 60 +++- memorytools/plugins/01_copytrans/transbox.py | 36 ++ memorytools/plugins/02_ocr/config.json | 2 +- memorytools/plugins/02_ocr/ocr.py | 4 +- memorytools/plugins/02_ocr/ocrbox.py | 77 +++++ memorytools/plugins/03_alert/alert.py | 5 +- memorytools/plugins/03_alert/alertbox.py | 19 + memorytools/plugins/03_alert/config.json | 2 +- memorytools/tools/basebox.py | 65 ++++ memorytools/tools/boxes.py | 169 --------- memorytools/tools/logger.py | 2 + memorytools/tools/utils.py | 22 +- 15 files changed, 513 insertions(+), 280 deletions(-) create mode 100644 memorytools/plugins/01_copytrans/transbox.py create mode 100644 memorytools/plugins/02_ocr/ocrbox.py create mode 100644 memorytools/plugins/03_alert/alertbox.py create mode 100644 memorytools/tools/basebox.py delete mode 100644 memorytools/tools/boxes.py diff --git a/memorytools/log/memorytools.log b/memorytools/log/memorytools.log index f0b33c5..b1f023d 100644 --- a/memorytools/log/memorytools.log +++ b/memorytools/log/memorytools.log @@ -1,67 +1,259 @@ -[2020-10-10 12:33:22,347 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 12:33:22,363 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 12:33:22,366 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 12:33:22,374 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 12:33:22,376 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 12:33:22,376 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 12:33:22,378 INFO] - [Memory Tools] ʼ... -[2020-10-10 12:33:26,327 INFO] - [OCRʶ] OCRʶ -[2020-10-10 12:33:30,753 INFO] - [MemoryTools] ˳ -[2020-10-10 12:33:41,390 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 12:33:41,405 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 12:33:41,407 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 12:33:41,415 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 12:33:41,416 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 12:33:41,417 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 12:33:41,418 INFO] - [Memory Tools] ʼ... -[2020-10-10 12:36:36,904 INFO] - [MemoryTools] ˳ -[2020-10-10 12:36:38,764 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 12:36:38,779 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 12:36:38,781 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 12:36:38,782 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 12:36:38,784 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 12:36:38,784 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 12:36:38,785 INFO] - [Memory Tools] ʼ... -[2020-10-10 12:36:46,056 INFO] - [MemoryTools] ˳ -[2020-10-10 12:36:54,620 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 12:36:54,635 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 12:36:54,638 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 12:36:54,639 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 12:36:54,641 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 12:36:54,641 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 12:36:54,642 INFO] - [Memory Tools] ʼ... -[2020-10-10 12:37:04,498 INFO] - [MemoryTools] ˳ - - -[2020-10-10 12:37:31,032 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 12:37:31,046 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 12:37:31,048 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 12:37:31,049 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 12:37:31,051 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 12:37:31,051 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 12:37:31,053 INFO] - [Memory Tools] ʼ... -[2020-10-10 12:37:40,888 INFO] - [MemoryTools] ˳ - - -[2020-10-10 12:38:55,575 INFO] - [MemoryTools] -[2020-10-10 12:38:55,787 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 12:38:55,801 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 12:38:55,804 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 12:38:55,805 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 12:38:55,806 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 12:38:55,807 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 12:38:55,808 INFO] - [Memory Tools] ʼ... -[2020-10-10 12:39:01,212 INFO] - [MemoryTools] ˳ - -[2020-10-10 12:39:11,268 INFO] - [MemoryTools] -[2020-10-10 12:39:11,481 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 12:39:11,497 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 12:39:11,500 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 12:39:11,501 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 12:39:11,503 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 12:39:11,503 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 12:39:11,505 INFO] - [MemoryTools] ʼ... -[2020-10-10 12:39:19,501 INFO] - [Ϣ] رϢ -[2020-10-10 12:39:23,637 INFO] - [Ϣ] ϢʱΪ 60 . -[2020-10-10 12:39:27,133 INFO] - [MemoryTools] ˳ - +[2020-10-10 12:33:22,347 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 12:33:22,363 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 12:33:22,366 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 12:33:22,374 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 12:33:22,376 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 12:33:22,376 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 12:33:22,378 INFO] - [Memory Tools] ʼ... +[2020-10-10 12:33:26,327 INFO] - [OCRʶ] OCRʶ +[2020-10-10 12:33:30,753 INFO] - [MemoryTools] ˳ +[2020-10-10 12:33:41,390 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 12:33:41,405 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 12:33:41,407 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 12:33:41,415 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 12:33:41,416 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 12:33:41,417 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 12:33:41,418 INFO] - [Memory Tools] ʼ... +[2020-10-10 12:36:36,904 INFO] - [MemoryTools] ˳ +[2020-10-10 12:36:38,764 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 12:36:38,779 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 12:36:38,781 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 12:36:38,782 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 12:36:38,784 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 12:36:38,784 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 12:36:38,785 INFO] - [Memory Tools] ʼ... +[2020-10-10 12:36:46,056 INFO] - [MemoryTools] ˳ +[2020-10-10 12:36:54,620 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 12:36:54,635 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 12:36:54,638 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 12:36:54,639 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 12:36:54,641 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 12:36:54,641 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 12:36:54,642 INFO] - [Memory Tools] ʼ... +[2020-10-10 12:37:04,498 INFO] - [MemoryTools] ˳ + + +[2020-10-10 12:37:31,032 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 12:37:31,046 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 12:37:31,048 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 12:37:31,049 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 12:37:31,051 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 12:37:31,051 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 12:37:31,053 INFO] - [Memory Tools] ʼ... +[2020-10-10 12:37:40,888 INFO] - [MemoryTools] ˳ + + +[2020-10-10 12:38:55,575 INFO] - [MemoryTools] +[2020-10-10 12:38:55,787 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 12:38:55,801 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 12:38:55,804 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 12:38:55,805 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 12:38:55,806 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 12:38:55,807 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 12:38:55,808 INFO] - [Memory Tools] ʼ... +[2020-10-10 12:39:01,212 INFO] - [MemoryTools] ˳ + +[2020-10-10 12:39:11,268 INFO] - [MemoryTools] +[2020-10-10 12:39:11,481 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 12:39:11,497 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 12:39:11,500 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 12:39:11,501 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 12:39:11,503 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 12:39:11,503 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 12:39:11,505 INFO] - [MemoryTools] ʼ... +[2020-10-10 12:39:19,501 INFO] - [Ϣ] رϢ +[2020-10-10 12:39:23,637 INFO] - [Ϣ] ϢʱΪ 60 . +[2020-10-10 12:39:27,133 INFO] - [MemoryTools] ˳ + +[2020-10-10 15:48:31,586 INFO] - [MemoryTools] +[2020-10-10 15:48:31,913 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 15:48:31,939 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 15:48:31,941 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 15:48:31,943 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 15:48:31,945 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 15:48:31,946 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 15:48:31,948 INFO] - [MemoryTools] ʼ... +[2020-10-10 15:48:48,104 INFO] - [Ʒ] Ʒ +[2020-10-10 15:48:48,205 INFO] - [Ʒ] аıΪ: self.translator = Translator(service_urls=['translate.google.cn']) +[2020-10-10 15:48:48,209 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 +[2020-10-10 15:49:10,020 INFO] - [Ʒ] аıΪ: text = self.translator.translate(sentence, dest=self.dest).text +[2020-10-10 15:49:10,020 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 +[2020-10-10 15:50:02,356 INFO] - [Ʒ] аıΪ: -->ӢģķӢģƵıӢĵıߣ򲻻ᷭ롣 +[2020-10-10 15:50:02,358 INFO] - [Ʒ] ıҪΪ: zh-cn, ռ: 1.0 +[2020-10-10 15:52:32,633 INFO] - [Ʒ] аıΪ: logger.info('[Ʒ] ԭһ£˲ʾ') +[2020-10-10 15:52:32,634 INFO] - [Ʒ] ıҪΪ: zh-cn, ռ: 0.8421052631578947 +[2020-10-10 15:53:02,053 INFO] - [MemoryTools] ˳ + +[2020-10-10 15:53:03,809 INFO] - [MemoryTools] +[2020-10-10 15:53:04,030 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 15:53:04,044 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 15:53:04,047 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 15:53:04,048 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 15:53:04,050 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 15:53:04,050 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 15:53:04,052 INFO] - [MemoryTools] ʼ... +[2020-10-10 15:53:04,163 INFO] - [Ʒ] аıΪ: logger.info('[Ʒ] ԭһ£˲ʾ') +[2020-10-10 15:53:04,166 INFO] - [Ʒ] ıҪΪ: zh-cn, ռ: 0.8421052631578947 +[2020-10-10 15:53:07,019 INFO] - [Ʒ] Ϊ: logger.info('[Copy translation] The translation is consistent with the original, so it is not displayed.') +[2020-10-10 15:53:20,722 INFO] - [MemoryTools] ˳ + +[2020-10-10 16:00:33,762 INFO] - [MemoryTools] +[2020-10-10 16:00:33,984 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 16:00:33,999 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 16:00:34,002 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 16:00:34,003 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 16:00:34,004 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 16:00:34,005 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 16:00:34,007 INFO] - [MemoryTools] ʼ... +[2020-10-10 16:00:34,115 INFO] - [Ʒ] аıΪ: logger.error("[Ʒ] ʧ: %s" % ce) +[2020-10-10 16:00:34,118 INFO] - [Ʒ] ıҪΪ: zh-cn, ռ: 0.6666666666666666 +[2020-10-10 16:00:36,284 INFO] - [Ʒ] Ϊ: logger.error("[Copy translation] Connection failed: %s"% ce) +[2020-10-10 16:00:44,604 INFO] - [MemoryTools] ˳ + +[2020-10-10 16:06:47,984 INFO] - [MemoryTools] +[2020-10-10 16:06:48,232 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 16:06:48,248 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 16:06:48,250 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 16:06:48,252 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 16:06:48,254 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 16:06:48,254 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 16:06:48,256 INFO] - [MemoryTools] ʼ... +[2020-10-10 16:06:48,360 INFO] - [Ʒ] аıΪ: +[2020-10-10 16:06:48,361 INFO] - [Ʒ] ıҪΪ: None, ռ: 0 +[2020-10-10 16:06:48,362 INFO] - [Ʒ] ıвӢģ˲. +[2020-10-10 16:06:52,844 INFO] - [Ʒ] аıΪ: self.src_text = ScrolledText(self, height=h1, background='#ffffff', font=("΢ź", 11)) + self.textbox = ScrolledText(self, height=h2, background='#ffffff', font=("΢ź", 11)) +[2020-10-10 16:06:52,847 INFO] - [Ʒ] ıҪΪ: en, ռ: 0.8181818181818182 +[2020-10-10 16:06:55,258 INFO] - [Ʒ] ԭһ£˲ʾ +[2020-10-10 16:07:00,168 INFO] - [Ʒ] аıΪ: ScrolledText(self, height=h2, background='#ffffff', font=("΢ź", 11)) +[2020-10-10 16:07:00,169 INFO] - [Ʒ] ıҪΪ: en, ռ: 0.7777777777777778 +[2020-10-10 16:07:00,423 INFO] - [Ʒ] ԭһ£˲ʾ +[2020-10-10 16:07:04,123 INFO] - [Ʒ] аıΪ: ScrolledText +[2020-10-10 16:07:04,123 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 +[2020-10-10 16:07:04,608 INFO] - [Ʒ] Ϊ: +[2020-10-10 16:07:15,762 INFO] - [MemoryTools] ˳ + +[2020-10-10 16:14:28,563 INFO] - [MemoryTools] +[2020-10-10 16:14:28,810 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 16:14:28,828 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 16:14:28,831 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 16:14:28,833 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 16:14:28,834 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 16:14:28,835 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 16:14:28,836 INFO] - [MemoryTools] ʼ... +[2020-10-10 16:14:28,943 INFO] - [Ʒ] аıΪ: self.textbox.insert(END, str(dest)) +[2020-10-10 16:14:28,947 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 +[2020-10-10 16:14:31,182 INFO] - [Ʒ] Ϊ: self.textbox.insertENDstrdest +[2020-10-10 16:14:40,779 INFO] - [MemoryTools] ˳ + +[2020-10-10 16:19:42,699 INFO] - [MemoryTools] +[2020-10-10 16:19:42,944 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 16:19:42,962 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 16:19:42,964 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 16:19:42,966 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 16:19:42,967 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 16:19:42,968 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 16:19:42,970 INFO] - [MemoryTools] ʼ... +[2020-10-10 16:19:43,077 INFO] - [Ʒ] аıΪ: END +[2020-10-10 16:19:43,080 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 +[2020-10-10 16:19:45,627 INFO] - [Ʒ] Ϊ: +[2020-10-10 16:19:57,982 INFO] - [MemoryTools] ˳ + +[2020-10-10 16:20:14,746 INFO] - [MemoryTools] +[2020-10-10 16:20:14,987 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 16:20:15,003 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 16:20:15,006 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 16:20:15,007 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 16:20:15,010 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 16:20:15,011 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 16:20:15,012 INFO] - [MemoryTools] ʼ... +[2020-10-10 16:20:15,118 INFO] - [Ʒ] аıΪ: END +[2020-10-10 16:20:15,121 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 +[2020-10-10 16:20:17,441 INFO] - [Ʒ] Ϊ: +[2020-10-10 16:21:12,184 INFO] - [MemoryTools] ˳ + +[2020-10-10 16:21:13,535 INFO] - [MemoryTools] +[2020-10-10 16:21:13,765 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 16:21:13,780 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 16:21:13,783 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 16:21:13,784 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 16:21:13,785 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 16:21:13,786 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 16:21:13,787 INFO] - [MemoryTools] ʼ... +[2020-10-10 16:21:13,900 INFO] - [Ʒ] аıΪ: END +[2020-10-10 16:21:13,903 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 +[2020-10-10 16:21:16,799 INFO] - [Ʒ] Ϊ: +[2020-10-10 16:21:33,740 INFO] - [MemoryTools] ˳ + +[2020-10-10 16:22:19,230 INFO] - [MemoryTools] +[2020-10-10 16:22:19,471 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 16:22:19,487 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 16:22:19,489 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 16:22:19,490 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 16:22:19,492 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 16:22:19,493 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 16:22:19,495 INFO] - [MemoryTools] ʼ... +[2020-10-10 16:22:19,610 INFO] - [Ʒ] аıΪ: src_text +[2020-10-10 16:22:19,614 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 +[2020-10-10 16:22:22,344 INFO] - [Ʒ] ԭһ£˲ʾ +[2020-10-10 16:22:27,046 INFO] - [Ʒ] аıΪ: ScrolledText +[2020-10-10 16:22:27,046 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 +[2020-10-10 16:22:27,311 INFO] - [Ʒ] Ϊ: +[2020-10-10 16:23:52,878 INFO] - [Ʒ] аıΪ: +[2020-10-10 16:23:52,879 INFO] - [Ʒ] ıҪΪ: None, ռ: 0 +[2020-10-10 16:23:52,880 INFO] - [Ʒ] ıвӢģ˲. +[2020-10-10 16:24:00,333 INFO] - [MemoryTools] ˳ + +[2020-10-10 16:29:30,864 INFO] - [MemoryTools] +[2020-10-10 16:30:19,303 INFO] - [MemoryTools] +[2020-10-10 16:30:48,749 INFO] - [MemoryTools] +[2020-10-10 16:31:12,347 INFO] - [MemoryTools] +[2020-10-10 16:31:56,084 INFO] - [MemoryTools] +[2020-10-10 16:32:47,858 INFO] - [MemoryTools] +[2020-10-10 16:32:48,095 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 16:32:48,112 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 16:32:48,115 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 16:32:48,116 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 16:32:48,119 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 16:32:48,120 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 16:32:48,123 INFO] - [MemoryTools] ʼ... +[2020-10-10 16:32:48,227 INFO] - [Ʒ] аıΪ: +[2020-10-10 16:32:48,228 INFO] - [Ʒ] ıҪΪ: None, ռ: 0 +[2020-10-10 16:32:48,228 INFO] - [Ʒ] ıвӢģ˲. +[2020-10-10 16:32:55,869 INFO] - [Ʒ] аıΪ: tools +[2020-10-10 16:32:55,872 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 +[2020-10-10 16:32:59,487 INFO] - [Ʒ] Ϊ: +[2020-10-10 16:33:28,388 INFO] - [MemoryTools] ˳ + +[2020-10-10 16:34:57,912 INFO] - [MemoryTools] +[2020-10-10 16:34:58,170 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 16:34:58,189 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 16:34:58,194 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 16:34:58,196 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 16:34:58,198 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 16:34:58,199 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 16:34:58,201 INFO] - [MemoryTools] ʼ... +[2020-10-10 16:34:58,303 INFO] - [Ʒ] аıΪ: # -*- coding: utf-8 -*- +[2020-10-10 16:34:58,306 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 +[2020-10-10 16:35:02,368 INFO] - [Ʒ] Ϊ: -*-룺utf-8-*- +[2020-10-10 16:35:02,622 INFO] - [Ʒ] رȥ +[2020-10-10 16:35:07,222 INFO] - [Ʒ] ȥ +[2020-10-10 16:35:10,739 INFO] - [Ʒ] رոƷ +[2020-10-10 16:35:32,320 INFO] - [OCRʶ] лOCRʶģʽΪ: ı +[2020-10-10 16:36:07,088 INFO] - [MemoryTools] ˳ + +[2020-10-10 16:48:04,262 INFO] - [MemoryTools] +[2020-10-10 16:48:04,483 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 16:48:04,523 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 16:48:04,533 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 16:48:04,535 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 16:48:04,536 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 16:48:04,537 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 16:48:04,538 INFO] - [MemoryTools] ʼ... +[2020-10-10 16:48:11,458 INFO] - [Ʒ] Ʒ +[2020-10-10 16:48:11,526 INFO] - [Ʒ] аıΪ: AlertBox +[2020-10-10 16:48:11,529 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 +[2020-10-10 16:48:13,371 INFO] - [Ʒ] Ϊ: +[2020-10-10 16:48:43,383 INFO] - [Ϣ] Ϣ +[2020-10-10 16:48:49,299 INFO] - [MemoryTools] ˳ + diff --git a/memorytools/plugins/01_copytrans/__init__.py b/memorytools/plugins/01_copytrans/__init__.py index d84c705..1e7c4ff 100644 --- a/memorytools/plugins/01_copytrans/__init__.py +++ b/memorytools/plugins/01_copytrans/__init__.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + from .copytrans import CopyTrans plugin = CopyTrans diff --git a/memorytools/plugins/01_copytrans/config.json b/memorytools/plugins/01_copytrans/config.json index 25b5e1e..d1fda99 100644 --- a/memorytools/plugins/01_copytrans/config.json +++ b/memorytools/plugins/01_copytrans/config.json @@ -1,5 +1,5 @@ { - "is_trans": false, + "is_trans": true, "newline": false, "strict": false, "mode": "both", diff --git a/memorytools/plugins/01_copytrans/copytrans.py b/memorytools/plugins/01_copytrans/copytrans.py index e0e191c..6d5f9e2 100644 --- a/memorytools/plugins/01_copytrans/copytrans.py +++ b/memorytools/plugins/01_copytrans/copytrans.py @@ -1,8 +1,10 @@ +# -*- coding: utf-8 -*- + from pathlib import Path from easydict import EasyDict -from tools.boxes import TextTextBox +from .transbox import TransBox from googletransx import Translator -from tools.utils import is_check, is_pick, judge_language, paste_clip +from tools.utils import is_check, is_pick, judge_language, paste_clip, copy_clip from tools.logger import logger from requests.exceptions import ConnectionError from plugins import BasePlugin, change_config @@ -10,11 +12,14 @@ class CopyTrans(BasePlugin): + """ + 一个复制翻译的插件,调用谷歌翻译的接口翻译剪切板中的文本 + """ def __init__(self, root) -> None: config_path = Path(__file__).parent / "config.json" super(CopyTrans, self).__init__("复制翻译", root, ICON.trans, config_path) - self.last = '' # 记录上次的剪切板内容 - self.translator = Translator(service_urls=['translate.google.cn']) # 获得翻译接口 + self.last = '' # 记录上次的剪切板内容 + self.translator = self.get_translator() # 获得翻译接口 def create_menu(self) -> tuple: menu_options = ( @@ -28,6 +33,10 @@ def create_menu(self) -> tuple: return menu_options + @classmethod + def get_translator(cls): + return Translator(service_urls=['translate.google.cn']) + @change_config def pause_trans(self, s): self.is_trans = not self.is_trans @@ -86,28 +95,42 @@ def pre_process(self, source): 如果是互译模式,根据检测结果设置源语言和目标语言。 再判断是否要去除其中的换行。 ''' + # 判断是否为空或与之前的内容一致 if source == "" or source == self.last: return None + # 去除文本两端的空格 text = source.strip() + logger.info("[复制翻译] 剪切板文本为: %s" % text) + # 检测文本的语言 src_language, score = judge_language(text) - msg = '检测为: %s, %s. 目标语言为: %s' % (src_language, score, self.dest) - logger.info("[复制翻译] " + msg) + msg = "[复制翻译] 文本的主要语言为: %s, 占比: %s" % (src_language, score) + logger.info(msg) + # 文本中不含中英文则不翻译 if not src_language: self.last = source + logger.info("[复制翻译] 文本中不含中英文,因此不翻译.") return None + # 文本中目标语言的占比过大则不翻译 if self.mode != 'both' and src_language == self.dest and score > 0.8: + logger.info("[复制翻译] 文本中目标语言的占比过大,因此不翻译.") self.last = source return None - + # 如果是中英互译,则根据检测的语言设置源语言和目标语言 if self.mode == 'both': self.src = src_language self.dest = 'en' if src_language == 'zh-cn' else 'zh-cn' - + # 去除换行符 sentence = self.remove_newline(text) return sentence def trans_text(self, sentence: str): + """ + 使用接口翻译文本,由于可能会失败,因此这里会重连三次 + :param sentence: 待翻译的文本 + :return: 翻译后的文本 + """ + text = sentence for i in range(3): try: if self.strict: @@ -116,15 +139,20 @@ def trans_text(self, sentence: str): text = self.translator.translate(sentence, dest=self.dest).text return text except ConnectionError as ce: - print(ce) - self.translator = Translator(service_urls=['translate.google.cn']) + logger.error("[复制翻译] 连接失败: %s" % ce) + self.translator = self.get_translator() text = str(ce) except Exception as e: - print(e) + logger.error("[复制翻译] 翻译出错: %s" % e) text = str(e) return text def trans(self, source: str): + """ + 对文本进行处理,看是否需要翻译,若否则不处理,若是则调用接口进行翻译并进行显示 + :param source: 待处理的文本 + :return: + """ sentence = self.pre_process(source) if not sentence: return None @@ -135,11 +163,11 @@ def trans(self, source: str): self.last = source logger.info('[复制翻译] 译文与原文一致,因此不显示。') return None - # print("%s\n%s\n" % (sentence, text)) - TextTextBox('翻译结果').show(sentence, text) - # paste = pasteClip() - # if paste == source: - # copyClip(sentence) + logger.info('[复制翻译] 翻译结果为: %s' % text) + TransBox(copy_trans=self).show(sentence, text) + paste = paste_clip() + if paste == source: + copy_clip(sentence) self.last = paste_clip() def start(self): diff --git a/memorytools/plugins/01_copytrans/transbox.py b/memorytools/plugins/01_copytrans/transbox.py new file mode 100644 index 0000000..0354c1b --- /dev/null +++ b/memorytools/plugins/01_copytrans/transbox.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +from tkinter.scrolledtext import ScrolledText +from tools.basebox import BaseBox, END +from tools.utils import get_text_line + + +class TransBox(BaseBox): + def __init__(self, title="翻译结果", copy_trans=None): + buttons = [('重新翻译', self.retrans), ('复制', self.copy)] + super(TransBox, self).__init__(buttons, title) + self.copy_trans = copy_trans + + def retrans(self): + """ + 根据用户的更改重新进行翻译 + """ + sentence = self.src_text.get("1.0", END) + text = self.copy_trans.trans_text(sentence) + self.textbox.delete("1.0", END) + self.textbox.insert(END, text) + + def show(self, src: str, dest: str): + h1 = min(10, max(5, get_text_line(src) + 1)) + h2 = min(10, max(5, get_text_line(dest) + 1)) + + self.src_text = ScrolledText(self, height=h1, background='#ffffff', font=("微软雅黑", 11)) + self.textbox = ScrolledText(self, height=h2, background='#ffffff', font=("微软雅黑", 11)) + + self.src_text.insert(END, str(src)) + self.src_text.config() + self.textbox.insert(END, str(dest)) + + self.src_text.pack(side='top', padx=10, pady=10) + self.textbox.pack(side='top', padx=10, pady=10) + + self.start() diff --git a/memorytools/plugins/02_ocr/config.json b/memorytools/plugins/02_ocr/config.json index 0fd8c3a..66e1472 100644 --- a/memorytools/plugins/02_ocr/config.json +++ b/memorytools/plugins/02_ocr/config.json @@ -1,5 +1,5 @@ { "is_ocr": true, "newline": false, - "mode": "math" + "mode": "text" } \ No newline at end of file diff --git a/memorytools/plugins/02_ocr/ocr.py b/memorytools/plugins/02_ocr/ocr.py index 7f16475..2e09af9 100644 --- a/memorytools/plugins/02_ocr/ocr.py +++ b/memorytools/plugins/02_ocr/ocr.py @@ -3,7 +3,7 @@ from . import BaiduOCR from . import LatexOCR from PIL import Image, ImageGrab, ImageDraw -from tools.boxes import ImageTextBox +from .ocrbox import OcrBox from tools.logger import logger from globals import BAIDU_ACCOUNTS, XUEERSI_ACCOUNTS, ICON from tools.utils import is_check, is_pick, get_rect, Color, copy_clip @@ -73,7 +73,7 @@ def start(self): text = str(e) copy_clip('') - ImageTextBox('OCR识别结果').show(im, text) + OcrBox('OCR识别结果').show(im, text) if __name__ == '__main__': diff --git a/memorytools/plugins/02_ocr/ocrbox.py b/memorytools/plugins/02_ocr/ocrbox.py new file mode 100644 index 0000000..dda5d51 --- /dev/null +++ b/memorytools/plugins/02_ocr/ocrbox.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +from tkinter import Label, END +from tkinter.scrolledtext import ScrolledText +from PIL import ImageTk +from tools.basebox import BaseBox + + +class OcrBox(BaseBox): + """ + 用来显示一张图片和一个文本框,会根据图片的大小和比例调整排列的方式 + """ + def __init__(self, title='OcrBox'): + buttons = [('复制', self.copy), ] + super(OcrBox, self).__init__(buttons, title) + + def resize_img(self, img, max_w: int, max_h: int): + """ + 对img进行缩放,使其长宽不超过给定的 max_w 和 max_h + """ + img_w, img_h = img.size + if img_w < max_w and img_h < max_h: + return img + + if img_w * max_h > img_h * max_w: + new_w = max_w + new_h = img_h * (new_w / img_w) + img = img.resize((int(new_w), int(new_h))) + else: + new_h = max_h + new_w = img_w * (new_h / img_h) + img = img.resize((int(new_w), int(new_h))) + + return img + + def set_size(self, img): + """ + 对图片进行处理,并限制窗口大小 + """ + img_w, img_h = img.size + aspect_ratio = self.screen_w / self.screen_h + + if img_w > img_h * aspect_ratio: + w, h = self.screen_w * 0.9, self.screen_h * 0.35 + img = self.resize_img(img, w, h) + img_w, img_h = img.size + width = max(self.screen_w // 3, img_w+20) + self.maxsize(width, int(self.screen_h*0.9)) + else: + w, h = self.screen_w * 0.45, self.screen_h * 0.7 + img = self.resize_img(img, w, h) + img_w, img_h = img.size + width = max(self.screen_w // 3, 2 * img_w + 70) + self.maxsize(width, int(self.screen_h*0.9)) + + return img + + def show(self, img, txt: str): + """ + 显示 + """ + img = self.set_size(img) + w, h = img.size + + self.tkImage = ImageTk.PhotoImage(image=img) + self.label = Label(self, image=self.tkImage) + self.textbox = ScrolledText(self, height=10, background='#ffffff', font=("微软雅黑", 11)) + self.textbox.insert(END, txt) + + aspect_ratio = self.screen_w / self.screen_h + if w >= h * aspect_ratio: + self.label.pack(side='top', padx=10, pady=10) + self.textbox.pack(side='top', padx=10, pady=10, fill='both') + else: + self.label.pack(side='left', padx=10, pady=10) + self.textbox.pack(side='right', padx=10, pady=10, fill='both') + + self.start() diff --git a/memorytools/plugins/03_alert/alert.py b/memorytools/plugins/03_alert/alert.py index 1dec012..9e8bc85 100644 --- a/memorytools/plugins/03_alert/alert.py +++ b/memorytools/plugins/03_alert/alert.py @@ -1,6 +1,5 @@ from time import time -from easydict import EasyDict -from tools.boxes import LabelBox +from .alertbox import AlertBox from globals import TEXT, ICON from tools.utils import is_check, is_pick from tools.logger import logger @@ -64,6 +63,6 @@ def alert(self): def start(self): if self.is_alert and self.alert(): alert_message = TEXT.alert % self.alert_time - LabelBox('危险警报').show(alert_message, '等你想要继续工作了再点我') + AlertBox('危险警报').show(alert_message, '等你想要继续工作了再点我') self.start_time = time() diff --git a/memorytools/plugins/03_alert/alertbox.py b/memorytools/plugins/03_alert/alertbox.py new file mode 100644 index 0000000..6ba4d8f --- /dev/null +++ b/memorytools/plugins/03_alert/alertbox.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from tkinter.ttk import Label +from tools.basebox import BaseBox + + +class AlertBox(BaseBox): + """ + 用于显示警告信息 + """ + def __init__(self, title='AlertBox'): + super(AlertBox, self).__init__([], title) + + def show(self, text: str, button=None): + self.minsize(self.screen_w//3, self.screen_h//5) + label = Label(self, text=text, font=("微软雅黑", 12)) + label.pack(padx=10, pady=50) + if button: + self.cancel_bth.config(text=button) + self.start() diff --git a/memorytools/plugins/03_alert/config.json b/memorytools/plugins/03_alert/config.json index 76876d9..21b6219 100644 --- a/memorytools/plugins/03_alert/config.json +++ b/memorytools/plugins/03_alert/config.json @@ -1,4 +1,4 @@ { - "is_alert": false, + "is_alert": true, "alert_time": 60 } \ No newline at end of file diff --git a/memorytools/tools/basebox.py b/memorytools/tools/basebox.py new file mode 100644 index 0000000..f2f2d3a --- /dev/null +++ b/memorytools/tools/basebox.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +""" +@file: basebox.py +@author: Memory +@date: 2020/3/23 +@description: 自定义弹出框的基类,可以在插件中调用 +""" + +from tkinter import Tk, END +from tkinter.ttk import Button, Frame +from tools.utils import copy_clip +from globals import ICON + + +class BaseBox(Tk): + """ + 弹出框的基类,默认居中显示,只有一个取消按钮, + 子类可以添加其他的组件 + """ + def __init__(self, buttons=[], title='Memory Tools'): + super(BaseBox, self).__init__() + self.set_window(title) + self.set_button(buttons) + + def set_window(self, title: str): + self.screen_w = self.winfo_screenwidth() + self.screen_h = self.winfo_screenheight() + self.title(title) + self.resizable(False, False) + self.iconbitmap(ICON.icon) + + min_w = self.screen_w // 3 + min_h = self.screen_h // 3 + self.minsize(min_w, min_h) + + def set_button(self, buttons: list): + ''' + 定义底部按钮 + ''' + self.btn_frame = Frame(self) + for text, command in buttons: + btn = Button(self.btn_frame, text=text, cursor='hand2', command=command) + btn.pack(side='left', padx=20, pady=10) + + self.cancel_bth = Button(self.btn_frame, text="取消", cursor='hand2', command=self.destroy) + self.cancel_bth.pack(side='left', padx=20, pady=10) + self.btn_frame.pack(side='bottom') + + def start(self, show=True): + ''' + 设置窗口位置,并运行显示消息框 + ''' + self.update() + width = self.winfo_width() + height = self.winfo_height() + pos_x = (self.screen_w - width)//2 + pos_y = max(0, (self.screen_h - height)//2-50) + size = '+%d+%d' % (pos_x, pos_y) + self.geometry(size) + self.mainloop() + + def copy(self): + txt = self.textbox.get("1.0", END) + copy_clip(txt) + self.destroy() diff --git a/memorytools/tools/boxes.py b/memorytools/tools/boxes.py deleted file mode 100644 index 0727519..0000000 --- a/memorytools/tools/boxes.py +++ /dev/null @@ -1,169 +0,0 @@ -''' -@file: boxes.py -@author: Memory -@date: 2020/3/23 -@description: 自定义的一些弹出框 -''' -from PIL import ImageTk -from tkinter import Tk, END -from tkinter.ttk import Label, Button, Frame -from tkinter.scrolledtext import ScrolledText, Text -from tools.utils import get_text_line, resize_img, copy_clip -from globals import ICON - - -class BaseBox(Tk): - """弹出框的基类""" - def __init__(self, buttons=[], title='Memory Tools'): - super(BaseBox, self).__init__() - self.set_window(title) - self.set_button(buttons) - - def set_window(self, title: str): - self.screen_w = self.winfo_screenwidth() - self.screen_h = self.winfo_screenheight() - self.title(title) - self.resizable(False, False) - self.iconbitmap(ICON.icon) - - min_w = self.screen_w // 3 - min_h = self.screen_h // 3 - self.minsize(min_w, min_h) - - def set_button(self, buttons: list): - ''' - 定义底部按钮 - ''' - self.btn_frame = Frame(self) - for text, command in buttons: - btn = Button(self.btn_frame, text=text, cursor='hand2', command=command) - btn.pack(side='left', padx=20, pady=10) - - self.cancel_bth = Button(self.btn_frame, text="取消", cursor='hand2', command=self.destroy) - self.cancel_bth.pack(side='left', padx=20, pady=10) - self.btn_frame.pack(side='bottom') - - def start(self, show=True): - ''' - 设置窗口位置,并运行显示消息框 - ''' - self.update() - width = self.winfo_width() - height = self.winfo_height() - pos_x = (self.screen_w - width)//2 - pos_y = max(0, (self.screen_h - height)//2-50) - size = '+%d+%d' % (pos_x, pos_y) - self.geometry(size) - self.mainloop() - - def copy(self): - txt = self.textbox.get("1.0", END) - copy_clip(txt) - self.destroy() - - -class TextTextBox(BaseBox): - def __init__(self, title='MemoryBox'): - buttons = [('复制', self.copy), ] - super(TextTextBox, self).__init__(buttons, title) - - def show(self, src: str, dest: str): - h1 = min(10, max(5, get_text_line(src) + 1)) - h2 = min(10, max(5, get_text_line(dest) + 1)) - - self.src_text = ScrolledText(self, height=h1, background='#ffffff', font=("微软雅黑", 11)) - self.textbox = ScrolledText(self, height=h2, background='#ffffff', font=("微软雅黑", 11)) - - self.src_text.insert(END, str(src)) - self.src_text.config(state='disabled') - self.textbox.insert(END, str(dest)) - - self.src_text.pack(side='top', padx=10, pady=10) - self.textbox.pack(side='top', padx=10, pady=10) - - self.start() - - -class ImageBox(BaseBox): - def __init__(self, title='MemoryBox'): - super(ImageBox, self).__init__([], title) - - def show(self, img): - img = resize_img(img, self.screen_w // 3, 100000) - w, h = img.size - self.geometry('%dx%d' % (w+20, self.screen_h*2//3)) - image = ImageTk.PhotoImage(image=img) - text = Text(self, height=100) - text.image_create(END, image=image) - text.pack(side='top', padx=10, fill='y') - self.cancel_bth.config(text='确定') - self.start() - - -class LabelBox(BaseBox): - """docstring for LabelBox""" - def __init__(self, title='MemoryBox'): - super(LabelBox, self).__init__([], title) - - def show(self, text: str, button=None): - self.minsize(self.screen_w//3, self.screen_h//5) - label = Label(self, text=text, font=("微软雅黑", 12)) - label.pack(padx=10, pady=50) - if button: - self.cancel_bth.config(text=button) - self.start() - - -class ImageTextBox(BaseBox): - '''用来显示一张图片和一个文本框,会根据图片的大小和比例调整排列的方式''' - def __init__(self, title='MemoryBox'): - buttons = [('复制', self.copy), ] - super(ImageTextBox, self).__init__(buttons, title) - - def set_size(self, img): - ''' - 对图片进行处理,并限制窗口大小 - ''' - img_w, img_h = img.size - aspect_ratio = self.screen_w / self.screen_h - - if img_w > img_h * aspect_ratio: - w, h = self.screen_w * 0.9, self.screen_h * 0.35 - img = resize_img(img, w, h) - img_w, img_h = img.size - width = max(self.screen_w // 3, img_w+20) - self.maxsize(width, int(self.screen_h*0.9)) - else: - w, h = self.screen_w * 0.45, self.screen_h * 0.7 - img = resize_img(img, w, h) - img_w, img_h = img.size - width = max(self.screen_w // 3, 2 * img_w + 70) - self.maxsize(width, int(self.screen_h*0.9)) - - return img - - def show(self, img, txt: str): - ''' - 显示 - ''' - img = self.set_size(img) - w, h = img.size - - self.tkImage = ImageTk.PhotoImage(image=img) - self.label = Label(self, image=self.tkImage) - self.textbox = ScrolledText(self, height=10, background='#ffffff', font=("微软雅黑", 11)) - self.textbox.insert(END, txt) - - aspect_ratio = self.screen_w / self.screen_h - if w >= h * aspect_ratio: - self.label.pack(side='top', padx=10, pady=10) - self.textbox.pack(side='top', padx=10, pady=10, fill='both') - else: - self.label.pack(side='left', padx=10, pady=10) - self.textbox.pack(side='right', padx=10, pady=10, fill='both') - - self.start() - - -if __name__ == '__main__': - LabelBox().show("虽然你关掉了休息提醒,但还是要注意身体!", '确认') diff --git a/memorytools/tools/logger.py b/memorytools/tools/logger.py index 12ca526..22e8859 100644 --- a/memorytools/tools/logger.py +++ b/memorytools/tools/logger.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + import logging import logging.handlers from sys import stdout diff --git a/memorytools/tools/utils.py b/memorytools/tools/utils.py index 713f67d..3260447 100644 --- a/memorytools/tools/utils.py +++ b/memorytools/tools/utils.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + import os import re import pyperclip @@ -79,26 +81,6 @@ def img_to_base64(image: str): return image_data_base64 -def resize_img(img, max_w: int, max_h: int): - """ - 对img进行缩放,使其长宽不超过给定的 max_w 和 max_h - """ - img_w, img_h = img.size - if img_w < max_w and img_h < max_h: - return img - - if img_w * max_h > img_h * max_w: - new_w = max_w - new_h = img_h * (new_w / img_w) - img = img.resize((int(new_w), int(new_h))) - else: - new_h = max_h - new_w = img_w * (new_h / img_h) - img = img.resize((int(new_w), int(new_h))) - - return img - - def is_check(check: bool): """是否选中(两种状态)""" return ICON.check if check else None From a2d894bab9d53a59ae06db59e430b86ed03b9b8e Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Sat, 10 Oct 2020 17:17:07 +0800 Subject: [PATCH 17/28] =?UTF-8?q?=E6=B7=BB=E5=8A=A0help=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- memorytools/globals.py | 6 ++ memorytools/log/memorytools.log | 79 +++++++++++++++++++ memorytools/memorytools.py | 12 +-- memorytools/plugins/01_copytrans/copytrans.py | 1 - memorytools/plugins/02_ocr/__init__.py | 2 + memorytools/plugins/02_ocr/baiduOCR.py | 1 + memorytools/plugins/02_ocr/ocr.py | 2 +- memorytools/plugins/02_ocr/xueersiOCR.py | 1 + memorytools/plugins/03_alert/__init__.py | 2 + memorytools/plugins/03_alert/alert.py | 1 + memorytools/plugins/04_help/__init__.py | 3 + memorytools/plugins/04_help/config.json | 1 + memorytools/plugins/04_help/help.py | 36 +++++++++ memorytools/plugins/__init__.py | 1 + memorytools/plugins/base.py | 4 +- memorytools/tools/utils.py | 3 +- 16 files changed, 142 insertions(+), 13 deletions(-) create mode 100644 memorytools/plugins/04_help/__init__.py create mode 100644 memorytools/plugins/04_help/config.json create mode 100644 memorytools/plugins/04_help/help.py diff --git a/memorytools/globals.py b/memorytools/globals.py index 9630d3f..64280e5 100644 --- a/memorytools/globals.py +++ b/memorytools/globals.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from string import punctuation from easydict import EasyDict from pathlib import Path @@ -29,6 +30,11 @@ class TEXT: alert = '你已经连续工作 %d 分钟了!是时候休息一下了!\ntip: 连续在电脑前工作太久容易脱发,得颈椎病,猝死。' +class URL: + github = "https://github.com/MemoryD/MemoryTools" + release = "https://github.com/MemoryD/MemoryTools/releases" + + def get_icon(): if not PATH.icon.exists(): PATH.icon.mkdir(parents=True, exist_ok=True) diff --git a/memorytools/log/memorytools.log b/memorytools/log/memorytools.log index b1f023d..0228694 100644 --- a/memorytools/log/memorytools.log +++ b/memorytools/log/memorytools.log @@ -257,3 +257,82 @@ [2020-10-10 16:48:43,383 INFO] - [Ϣ] Ϣ [2020-10-10 16:48:49,299 INFO] - [MemoryTools] ˳ +[2020-10-10 16:54:51,913 INFO] - [MemoryTools] +[2020-10-10 16:54:52,156 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 16:54:52,203 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 16:54:52,216 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 16:54:52,217 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 16:54:52,220 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 16:54:52,220 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 16:54:52,222 INFO] - [MemoryTools] ʼ... +[2020-10-10 16:54:52,330 INFO] - [Ʒ] аıΪ: +[2020-10-10 16:54:52,331 INFO] - [Ʒ] ıҪΪ: None, ռ: 0 +[2020-10-10 16:54:52,332 INFO] - [Ʒ] ıвӢģ˲. +[2020-10-10 16:54:58,446 INFO] - [MemoryTools] ˳ + +[2020-10-10 17:08:52,907 INFO] - [MemoryTools] +[2020-10-10 17:08:53,120 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 17:08:53,155 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 17:08:53,157 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 17:09:13,577 INFO] - [MemoryTools] +[2020-10-10 17:09:13,778 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 17:09:13,809 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 17:09:13,813 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 17:09:13,817 INFO] - [plugin init] ֲ: plugins.04_help +[2020-10-10 17:09:13,818 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 17:09:13,820 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 17:09:13,821 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 17:10:57,256 INFO] - [MemoryTools] +[2020-10-10 17:10:57,466 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 17:10:57,498 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 17:10:57,502 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 17:10:57,504 INFO] - [plugin init] ֲ: plugins.04_help +[2020-10-10 17:10:57,505 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 17:10:57,507 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 17:10:57,507 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 17:10:57,508 INFO] - [plugin base] ʼ: +[2020-10-10 17:10:57,509 INFO] - [MemoryTools] ʼ... +[2020-10-10 17:10:57,625 INFO] - [Ʒ] аıΪ: # -*- coding: utf-8 -*- +[2020-10-10 17:10:57,629 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 +[2020-10-10 17:10:59,246 INFO] - [Ʒ] Ϊ: -*-룺utf-8-*- +[2020-10-10 17:12:12,125 INFO] - [Ʒ] аıΪ: "https://github.com/MemoryD/MemoryTools" +[2020-10-10 17:12:12,126 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 +[2020-10-10 17:12:12,565 INFO] - [Ʒ] Ϊ: "HTTPS://GitHub.com/memory D/memory tools" +[2020-10-10 17:13:17,495 INFO] - [Ʒ] аıΪ: https://github.com/MemoryD/MemoryTools/releases +[2020-10-10 17:13:17,496 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 +[2020-10-10 17:13:18,140 INFO] - [Ʒ] Ϊ: HTTPS://GitHub.com/memory D/memory tools/releases +[2020-10-10 17:15:41,938 INFO] - [Ʒ] аıΪ: ("־", None, self.open_log, True), +[2020-10-10 17:15:41,938 INFO] - [Ʒ] ıҪΪ: en, ռ: 0.75 +[2020-10-10 17:15:42,192 INFO] - [Ʒ] ԭһ£˲ʾ +[2020-10-10 17:16:08,824 INFO] - [MemoryTools] ˳ + +[2020-10-10 17:16:10,301 INFO] - [MemoryTools] +[2020-10-10 17:16:10,510 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 17:16:10,542 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 17:16:10,545 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 17:16:10,550 INFO] - [plugin init] ֲ: plugins.04_help +[2020-10-10 17:16:10,551 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 17:16:10,552 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 17:16:10,553 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 17:16:10,554 INFO] - [plugin base] ʼ: +[2020-10-10 17:16:10,555 INFO] - [MemoryTools] ʼ... +[2020-10-10 17:16:10,659 INFO] - [Ʒ] аıΪ: ("־", None, self.open_log, True), +[2020-10-10 17:16:10,662 INFO] - [Ʒ] ıҪΪ: en, ռ: 0.75 +[2020-10-10 17:16:12,868 INFO] - [Ʒ] ԭһ£˲ʾ +[2020-10-10 17:16:25,172 INFO] - [MemoryTools] ˳ + +[2020-10-10 17:16:27,036 INFO] - [MemoryTools] +[2020-10-10 17:16:27,236 INFO] - [plugin init] ֲ: plugins.01_copytrans +[2020-10-10 17:16:27,268 INFO] - [plugin init] ֲ: plugins.02_ocr +[2020-10-10 17:16:27,271 INFO] - [plugin init] ֲ: plugins.03_alert +[2020-10-10 17:16:27,276 INFO] - [plugin init] ֲ: plugins.04_help +[2020-10-10 17:16:27,277 INFO] - [plugin base] ʼ: Ʒ +[2020-10-10 17:16:27,278 INFO] - [plugin base] ʼ: OCRʶ +[2020-10-10 17:16:27,279 INFO] - [plugin base] ʼ: Ϣ +[2020-10-10 17:16:27,280 INFO] - [plugin base] ʼ: +[2020-10-10 17:16:27,281 INFO] - [MemoryTools] ʼ... +[2020-10-10 17:16:27,384 INFO] - [Ʒ] аıΪ: ("־", None, self.open_log, True), +[2020-10-10 17:16:27,387 INFO] - [Ʒ] ıҪΪ: en, ռ: 0.75 +[2020-10-10 17:16:29,641 INFO] - [Ʒ] ԭһ£˲ʾ +[2020-10-10 17:16:45,969 INFO] - [MemoryTools] ˳ + diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index b1e931b..e953713 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + from webbrowser import open as open_web from time import sleep from tools.logger import logger @@ -35,7 +37,7 @@ def create_menu(self): menu_options = [] for plugin in self.plugins: menu_options.append(plugin.init_menu()) - menu_options.append(('关于', ICON.about, self.about, True)) + # menu_options.append(('关于', ICON.about, self.about, True)) return tuple(menu_options) @@ -45,12 +47,6 @@ def refresh_menu(self): """ self.systray.refreshMenu(self.create_menu()) - def about(self, s: SysTrayIcon): - """ - 菜单中的 关于 选项 - """ - open_web("https://github.com/MemoryD/MemoryTools") - def bye(self, s: SysTrayIcon): """ 退出程序 @@ -70,7 +66,7 @@ def run(self): try: plugin.start() except Exception as e: - logger.error(e) + logger.error("[MemoryTools] %s" % e) if __name__ == '__main__': diff --git a/memorytools/plugins/01_copytrans/copytrans.py b/memorytools/plugins/01_copytrans/copytrans.py index 6d5f9e2..7073258 100644 --- a/memorytools/plugins/01_copytrans/copytrans.py +++ b/memorytools/plugins/01_copytrans/copytrans.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- from pathlib import Path -from easydict import EasyDict from .transbox import TransBox from googletransx import Translator from tools.utils import is_check, is_pick, judge_language, paste_clip, copy_clip diff --git a/memorytools/plugins/02_ocr/__init__.py b/memorytools/plugins/02_ocr/__init__.py index d6f07ef..e3d38d1 100644 --- a/memorytools/plugins/02_ocr/__init__.py +++ b/memorytools/plugins/02_ocr/__init__.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + from .baiduOCR import BaiduOCR from .xueersiOCR import LatexOCR from .ocr import OCR diff --git a/memorytools/plugins/02_ocr/baiduOCR.py b/memorytools/plugins/02_ocr/baiduOCR.py index 248f0d3..be1e472 100644 --- a/memorytools/plugins/02_ocr/baiduOCR.py +++ b/memorytools/plugins/02_ocr/baiduOCR.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from aip import AipOcr from PIL import Image from tools.utils import pil2bytes diff --git a/memorytools/plugins/02_ocr/ocr.py b/memorytools/plugins/02_ocr/ocr.py index 2e09af9..972f629 100644 --- a/memorytools/plugins/02_ocr/ocr.py +++ b/memorytools/plugins/02_ocr/ocr.py @@ -1,5 +1,5 @@ +# -*- coding: utf-8 -*- from pathlib import Path -from easydict import EasyDict from . import BaiduOCR from . import LatexOCR from PIL import Image, ImageGrab, ImageDraw diff --git a/memorytools/plugins/02_ocr/xueersiOCR.py b/memorytools/plugins/02_ocr/xueersiOCR.py index 6ac0555..efe58f0 100644 --- a/memorytools/plugins/02_ocr/xueersiOCR.py +++ b/memorytools/plugins/02_ocr/xueersiOCR.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from time import sleep, time from random import randint, choice from PIL import Image diff --git a/memorytools/plugins/03_alert/__init__.py b/memorytools/plugins/03_alert/__init__.py index 97c1058..dfa4353 100644 --- a/memorytools/plugins/03_alert/__init__.py +++ b/memorytools/plugins/03_alert/__init__.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + from .alert import Alert plugin = Alert diff --git a/memorytools/plugins/03_alert/alert.py b/memorytools/plugins/03_alert/alert.py index 9e8bc85..55cffba 100644 --- a/memorytools/plugins/03_alert/alert.py +++ b/memorytools/plugins/03_alert/alert.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from time import time from .alertbox import AlertBox from globals import TEXT, ICON diff --git a/memorytools/plugins/04_help/__init__.py b/memorytools/plugins/04_help/__init__.py new file mode 100644 index 0000000..2698908 --- /dev/null +++ b/memorytools/plugins/04_help/__init__.py @@ -0,0 +1,3 @@ +from .help import Help + +plugin = Help diff --git a/memorytools/plugins/04_help/config.json b/memorytools/plugins/04_help/config.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/memorytools/plugins/04_help/config.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/memorytools/plugins/04_help/help.py b/memorytools/plugins/04_help/help.py new file mode 100644 index 0000000..1e29340 --- /dev/null +++ b/memorytools/plugins/04_help/help.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +from os import startfile +from pathlib import Path +from webbrowser import open as open_web +from globals import ICON, PATH, URL +from plugins import BasePlugin + + +class Help(BasePlugin): + def __init__(self, root) -> None: + config_path = Path(__file__).parent / "config.json" + super(Help, self).__init__("帮助", root, ICON.about, config_path) + + def about(self, s): + """ + 菜单中的 关于 选项 + """ + open_web(URL.github) + + def check_update(self, s): + open_web(URL.release) + + def open_log(self, s): + startfile(PATH.log.absolute()) + + def create_menu(self) -> tuple: + menu_options = ( + ("关于", None, self.about, True), + ("日志", None, self.open_log, True), + ("更新", None, self.check_update, True), + ) + + return menu_options + + def start(self) -> None: + pass diff --git a/memorytools/plugins/__init__.py b/memorytools/plugins/__init__.py index 93cb069..0f54a1c 100644 --- a/memorytools/plugins/__init__.py +++ b/memorytools/plugins/__init__.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from importlib import import_module from pathlib import Path from tools.logger import logger diff --git a/memorytools/plugins/base.py b/memorytools/plugins/base.py index 729113c..1ebf5df 100644 --- a/memorytools/plugins/base.py +++ b/memorytools/plugins/base.py @@ -1,4 +1,6 @@ +# -*- coding: utf-8 -*- import json +from pathlib import Path from easydict import EasyDict from tools.logger import logger @@ -30,7 +32,7 @@ class BasePlugin(object): 2.3 config.json:托盘菜单配置文件,里面的属性会被绑定到 BasePlugin 子类中 具体可以参阅plugins文件夹下面的几个插件。 """ - def __init__(self, name: str, root, icon: str, config_path): + def __init__(self, name: str, root, icon: str, config_path: Path): """ :param name: 该插件的名字,会显示在托盘菜单中 :param root: MemoryTools类,会由主程序自动传入 diff --git a/memorytools/tools/utils.py b/memorytools/tools/utils.py index 3260447..cfbc7ad 100644 --- a/memorytools/tools/utils.py +++ b/memorytools/tools/utils.py @@ -4,10 +4,9 @@ import re import pyperclip from time import sleep -from base64 import b64decode, b64encode +from base64 import b64encode from urllib.parse import quote from io import BytesIO -from easydict import EasyDict from globals import * From 830031175f01e27f54bdd6d5f9676b5264ee74ce Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Sat, 10 Oct 2020 17:23:23 +0800 Subject: [PATCH 18/28] =?UTF-8?q?=E5=B0=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +- .idea/.gitignore | 3 - .idea/MemoryTools.iml | 8 - .../inspectionProfiles/profiles_settings.xml | 6 - .idea/misc.xml | 4 - .idea/modules.xml | 8 - .idea/vcs.xml | 6 - memorytools/globals.py | 2 +- memorytools/log/memorytools.log | 338 ------------------ memorytools/plugins/config.json | 19 - 10 files changed, 4 insertions(+), 394 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/MemoryTools.iml delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml delete mode 100644 memorytools/log/memorytools.log delete mode 100644 memorytools/plugins/config.json diff --git a/.gitignore b/.gitignore index 88c319c..6400050 100644 --- a/.gitignore +++ b/.gitignore @@ -7,5 +7,7 @@ memorytools.egg-info/ test/ src/ memorytools/__pycache__/ +memorytools/log/ +*/__pycache__/ upx-3.95-win64/ -.idea/ \ No newline at end of file +.idea/ diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/MemoryTools.iml b/.idea/MemoryTools.iml deleted file mode 100644 index 508668e..0000000 --- a/.idea/MemoryTools.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2d..0000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index b458927..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index ad39e5c..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/memorytools/globals.py b/memorytools/globals.py index 64280e5..30a79fe 100644 --- a/memorytools/globals.py +++ b/memorytools/globals.py @@ -26,7 +26,7 @@ class PATH: class TEXT: - hover = "Memory Tools" + hover = "Memory Tools v1.8.0" alert = '你已经连续工作 %d 分钟了!是时候休息一下了!\ntip: 连续在电脑前工作太久容易脱发,得颈椎病,猝死。' diff --git a/memorytools/log/memorytools.log b/memorytools/log/memorytools.log deleted file mode 100644 index 0228694..0000000 --- a/memorytools/log/memorytools.log +++ /dev/null @@ -1,338 +0,0 @@ -[2020-10-10 12:33:22,347 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 12:33:22,363 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 12:33:22,366 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 12:33:22,374 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 12:33:22,376 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 12:33:22,376 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 12:33:22,378 INFO] - [Memory Tools] ʼ... -[2020-10-10 12:33:26,327 INFO] - [OCRʶ] OCRʶ -[2020-10-10 12:33:30,753 INFO] - [MemoryTools] ˳ -[2020-10-10 12:33:41,390 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 12:33:41,405 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 12:33:41,407 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 12:33:41,415 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 12:33:41,416 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 12:33:41,417 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 12:33:41,418 INFO] - [Memory Tools] ʼ... -[2020-10-10 12:36:36,904 INFO] - [MemoryTools] ˳ -[2020-10-10 12:36:38,764 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 12:36:38,779 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 12:36:38,781 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 12:36:38,782 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 12:36:38,784 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 12:36:38,784 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 12:36:38,785 INFO] - [Memory Tools] ʼ... -[2020-10-10 12:36:46,056 INFO] - [MemoryTools] ˳ -[2020-10-10 12:36:54,620 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 12:36:54,635 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 12:36:54,638 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 12:36:54,639 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 12:36:54,641 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 12:36:54,641 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 12:36:54,642 INFO] - [Memory Tools] ʼ... -[2020-10-10 12:37:04,498 INFO] - [MemoryTools] ˳ - - -[2020-10-10 12:37:31,032 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 12:37:31,046 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 12:37:31,048 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 12:37:31,049 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 12:37:31,051 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 12:37:31,051 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 12:37:31,053 INFO] - [Memory Tools] ʼ... -[2020-10-10 12:37:40,888 INFO] - [MemoryTools] ˳ - - -[2020-10-10 12:38:55,575 INFO] - [MemoryTools] -[2020-10-10 12:38:55,787 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 12:38:55,801 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 12:38:55,804 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 12:38:55,805 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 12:38:55,806 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 12:38:55,807 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 12:38:55,808 INFO] - [Memory Tools] ʼ... -[2020-10-10 12:39:01,212 INFO] - [MemoryTools] ˳ - -[2020-10-10 12:39:11,268 INFO] - [MemoryTools] -[2020-10-10 12:39:11,481 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 12:39:11,497 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 12:39:11,500 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 12:39:11,501 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 12:39:11,503 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 12:39:11,503 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 12:39:11,505 INFO] - [MemoryTools] ʼ... -[2020-10-10 12:39:19,501 INFO] - [Ϣ] رϢ -[2020-10-10 12:39:23,637 INFO] - [Ϣ] ϢʱΪ 60 . -[2020-10-10 12:39:27,133 INFO] - [MemoryTools] ˳ - -[2020-10-10 15:48:31,586 INFO] - [MemoryTools] -[2020-10-10 15:48:31,913 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 15:48:31,939 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 15:48:31,941 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 15:48:31,943 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 15:48:31,945 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 15:48:31,946 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 15:48:31,948 INFO] - [MemoryTools] ʼ... -[2020-10-10 15:48:48,104 INFO] - [Ʒ] Ʒ -[2020-10-10 15:48:48,205 INFO] - [Ʒ] аıΪ: self.translator = Translator(service_urls=['translate.google.cn']) -[2020-10-10 15:48:48,209 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 -[2020-10-10 15:49:10,020 INFO] - [Ʒ] аıΪ: text = self.translator.translate(sentence, dest=self.dest).text -[2020-10-10 15:49:10,020 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 -[2020-10-10 15:50:02,356 INFO] - [Ʒ] аıΪ: -->ӢģķӢģƵıӢĵıߣ򲻻ᷭ롣 -[2020-10-10 15:50:02,358 INFO] - [Ʒ] ıҪΪ: zh-cn, ռ: 1.0 -[2020-10-10 15:52:32,633 INFO] - [Ʒ] аıΪ: logger.info('[Ʒ] ԭһ£˲ʾ') -[2020-10-10 15:52:32,634 INFO] - [Ʒ] ıҪΪ: zh-cn, ռ: 0.8421052631578947 -[2020-10-10 15:53:02,053 INFO] - [MemoryTools] ˳ - -[2020-10-10 15:53:03,809 INFO] - [MemoryTools] -[2020-10-10 15:53:04,030 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 15:53:04,044 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 15:53:04,047 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 15:53:04,048 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 15:53:04,050 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 15:53:04,050 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 15:53:04,052 INFO] - [MemoryTools] ʼ... -[2020-10-10 15:53:04,163 INFO] - [Ʒ] аıΪ: logger.info('[Ʒ] ԭһ£˲ʾ') -[2020-10-10 15:53:04,166 INFO] - [Ʒ] ıҪΪ: zh-cn, ռ: 0.8421052631578947 -[2020-10-10 15:53:07,019 INFO] - [Ʒ] Ϊ: logger.info('[Copy translation] The translation is consistent with the original, so it is not displayed.') -[2020-10-10 15:53:20,722 INFO] - [MemoryTools] ˳ - -[2020-10-10 16:00:33,762 INFO] - [MemoryTools] -[2020-10-10 16:00:33,984 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 16:00:33,999 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 16:00:34,002 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 16:00:34,003 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 16:00:34,004 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 16:00:34,005 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 16:00:34,007 INFO] - [MemoryTools] ʼ... -[2020-10-10 16:00:34,115 INFO] - [Ʒ] аıΪ: logger.error("[Ʒ] ʧ: %s" % ce) -[2020-10-10 16:00:34,118 INFO] - [Ʒ] ıҪΪ: zh-cn, ռ: 0.6666666666666666 -[2020-10-10 16:00:36,284 INFO] - [Ʒ] Ϊ: logger.error("[Copy translation] Connection failed: %s"% ce) -[2020-10-10 16:00:44,604 INFO] - [MemoryTools] ˳ - -[2020-10-10 16:06:47,984 INFO] - [MemoryTools] -[2020-10-10 16:06:48,232 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 16:06:48,248 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 16:06:48,250 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 16:06:48,252 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 16:06:48,254 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 16:06:48,254 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 16:06:48,256 INFO] - [MemoryTools] ʼ... -[2020-10-10 16:06:48,360 INFO] - [Ʒ] аıΪ: -[2020-10-10 16:06:48,361 INFO] - [Ʒ] ıҪΪ: None, ռ: 0 -[2020-10-10 16:06:48,362 INFO] - [Ʒ] ıвӢģ˲. -[2020-10-10 16:06:52,844 INFO] - [Ʒ] аıΪ: self.src_text = ScrolledText(self, height=h1, background='#ffffff', font=("΢ź", 11)) - self.textbox = ScrolledText(self, height=h2, background='#ffffff', font=("΢ź", 11)) -[2020-10-10 16:06:52,847 INFO] - [Ʒ] ıҪΪ: en, ռ: 0.8181818181818182 -[2020-10-10 16:06:55,258 INFO] - [Ʒ] ԭһ£˲ʾ -[2020-10-10 16:07:00,168 INFO] - [Ʒ] аıΪ: ScrolledText(self, height=h2, background='#ffffff', font=("΢ź", 11)) -[2020-10-10 16:07:00,169 INFO] - [Ʒ] ıҪΪ: en, ռ: 0.7777777777777778 -[2020-10-10 16:07:00,423 INFO] - [Ʒ] ԭһ£˲ʾ -[2020-10-10 16:07:04,123 INFO] - [Ʒ] аıΪ: ScrolledText -[2020-10-10 16:07:04,123 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 -[2020-10-10 16:07:04,608 INFO] - [Ʒ] Ϊ: -[2020-10-10 16:07:15,762 INFO] - [MemoryTools] ˳ - -[2020-10-10 16:14:28,563 INFO] - [MemoryTools] -[2020-10-10 16:14:28,810 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 16:14:28,828 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 16:14:28,831 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 16:14:28,833 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 16:14:28,834 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 16:14:28,835 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 16:14:28,836 INFO] - [MemoryTools] ʼ... -[2020-10-10 16:14:28,943 INFO] - [Ʒ] аıΪ: self.textbox.insert(END, str(dest)) -[2020-10-10 16:14:28,947 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 -[2020-10-10 16:14:31,182 INFO] - [Ʒ] Ϊ: self.textbox.insertENDstrdest -[2020-10-10 16:14:40,779 INFO] - [MemoryTools] ˳ - -[2020-10-10 16:19:42,699 INFO] - [MemoryTools] -[2020-10-10 16:19:42,944 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 16:19:42,962 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 16:19:42,964 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 16:19:42,966 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 16:19:42,967 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 16:19:42,968 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 16:19:42,970 INFO] - [MemoryTools] ʼ... -[2020-10-10 16:19:43,077 INFO] - [Ʒ] аıΪ: END -[2020-10-10 16:19:43,080 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 -[2020-10-10 16:19:45,627 INFO] - [Ʒ] Ϊ: -[2020-10-10 16:19:57,982 INFO] - [MemoryTools] ˳ - -[2020-10-10 16:20:14,746 INFO] - [MemoryTools] -[2020-10-10 16:20:14,987 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 16:20:15,003 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 16:20:15,006 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 16:20:15,007 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 16:20:15,010 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 16:20:15,011 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 16:20:15,012 INFO] - [MemoryTools] ʼ... -[2020-10-10 16:20:15,118 INFO] - [Ʒ] аıΪ: END -[2020-10-10 16:20:15,121 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 -[2020-10-10 16:20:17,441 INFO] - [Ʒ] Ϊ: -[2020-10-10 16:21:12,184 INFO] - [MemoryTools] ˳ - -[2020-10-10 16:21:13,535 INFO] - [MemoryTools] -[2020-10-10 16:21:13,765 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 16:21:13,780 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 16:21:13,783 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 16:21:13,784 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 16:21:13,785 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 16:21:13,786 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 16:21:13,787 INFO] - [MemoryTools] ʼ... -[2020-10-10 16:21:13,900 INFO] - [Ʒ] аıΪ: END -[2020-10-10 16:21:13,903 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 -[2020-10-10 16:21:16,799 INFO] - [Ʒ] Ϊ: -[2020-10-10 16:21:33,740 INFO] - [MemoryTools] ˳ - -[2020-10-10 16:22:19,230 INFO] - [MemoryTools] -[2020-10-10 16:22:19,471 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 16:22:19,487 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 16:22:19,489 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 16:22:19,490 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 16:22:19,492 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 16:22:19,493 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 16:22:19,495 INFO] - [MemoryTools] ʼ... -[2020-10-10 16:22:19,610 INFO] - [Ʒ] аıΪ: src_text -[2020-10-10 16:22:19,614 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 -[2020-10-10 16:22:22,344 INFO] - [Ʒ] ԭһ£˲ʾ -[2020-10-10 16:22:27,046 INFO] - [Ʒ] аıΪ: ScrolledText -[2020-10-10 16:22:27,046 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 -[2020-10-10 16:22:27,311 INFO] - [Ʒ] Ϊ: -[2020-10-10 16:23:52,878 INFO] - [Ʒ] аıΪ: -[2020-10-10 16:23:52,879 INFO] - [Ʒ] ıҪΪ: None, ռ: 0 -[2020-10-10 16:23:52,880 INFO] - [Ʒ] ıвӢģ˲. -[2020-10-10 16:24:00,333 INFO] - [MemoryTools] ˳ - -[2020-10-10 16:29:30,864 INFO] - [MemoryTools] -[2020-10-10 16:30:19,303 INFO] - [MemoryTools] -[2020-10-10 16:30:48,749 INFO] - [MemoryTools] -[2020-10-10 16:31:12,347 INFO] - [MemoryTools] -[2020-10-10 16:31:56,084 INFO] - [MemoryTools] -[2020-10-10 16:32:47,858 INFO] - [MemoryTools] -[2020-10-10 16:32:48,095 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 16:32:48,112 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 16:32:48,115 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 16:32:48,116 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 16:32:48,119 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 16:32:48,120 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 16:32:48,123 INFO] - [MemoryTools] ʼ... -[2020-10-10 16:32:48,227 INFO] - [Ʒ] аıΪ: -[2020-10-10 16:32:48,228 INFO] - [Ʒ] ıҪΪ: None, ռ: 0 -[2020-10-10 16:32:48,228 INFO] - [Ʒ] ıвӢģ˲. -[2020-10-10 16:32:55,869 INFO] - [Ʒ] аıΪ: tools -[2020-10-10 16:32:55,872 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 -[2020-10-10 16:32:59,487 INFO] - [Ʒ] Ϊ: -[2020-10-10 16:33:28,388 INFO] - [MemoryTools] ˳ - -[2020-10-10 16:34:57,912 INFO] - [MemoryTools] -[2020-10-10 16:34:58,170 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 16:34:58,189 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 16:34:58,194 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 16:34:58,196 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 16:34:58,198 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 16:34:58,199 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 16:34:58,201 INFO] - [MemoryTools] ʼ... -[2020-10-10 16:34:58,303 INFO] - [Ʒ] аıΪ: # -*- coding: utf-8 -*- -[2020-10-10 16:34:58,306 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 -[2020-10-10 16:35:02,368 INFO] - [Ʒ] Ϊ: -*-룺utf-8-*- -[2020-10-10 16:35:02,622 INFO] - [Ʒ] رȥ -[2020-10-10 16:35:07,222 INFO] - [Ʒ] ȥ -[2020-10-10 16:35:10,739 INFO] - [Ʒ] رոƷ -[2020-10-10 16:35:32,320 INFO] - [OCRʶ] лOCRʶģʽΪ: ı -[2020-10-10 16:36:07,088 INFO] - [MemoryTools] ˳ - -[2020-10-10 16:48:04,262 INFO] - [MemoryTools] -[2020-10-10 16:48:04,483 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 16:48:04,523 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 16:48:04,533 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 16:48:04,535 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 16:48:04,536 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 16:48:04,537 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 16:48:04,538 INFO] - [MemoryTools] ʼ... -[2020-10-10 16:48:11,458 INFO] - [Ʒ] Ʒ -[2020-10-10 16:48:11,526 INFO] - [Ʒ] аıΪ: AlertBox -[2020-10-10 16:48:11,529 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 -[2020-10-10 16:48:13,371 INFO] - [Ʒ] Ϊ: -[2020-10-10 16:48:43,383 INFO] - [Ϣ] Ϣ -[2020-10-10 16:48:49,299 INFO] - [MemoryTools] ˳ - -[2020-10-10 16:54:51,913 INFO] - [MemoryTools] -[2020-10-10 16:54:52,156 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 16:54:52,203 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 16:54:52,216 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 16:54:52,217 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 16:54:52,220 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 16:54:52,220 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 16:54:52,222 INFO] - [MemoryTools] ʼ... -[2020-10-10 16:54:52,330 INFO] - [Ʒ] аıΪ: -[2020-10-10 16:54:52,331 INFO] - [Ʒ] ıҪΪ: None, ռ: 0 -[2020-10-10 16:54:52,332 INFO] - [Ʒ] ıвӢģ˲. -[2020-10-10 16:54:58,446 INFO] - [MemoryTools] ˳ - -[2020-10-10 17:08:52,907 INFO] - [MemoryTools] -[2020-10-10 17:08:53,120 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 17:08:53,155 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 17:08:53,157 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 17:09:13,577 INFO] - [MemoryTools] -[2020-10-10 17:09:13,778 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 17:09:13,809 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 17:09:13,813 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 17:09:13,817 INFO] - [plugin init] ֲ: plugins.04_help -[2020-10-10 17:09:13,818 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 17:09:13,820 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 17:09:13,821 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 17:10:57,256 INFO] - [MemoryTools] -[2020-10-10 17:10:57,466 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 17:10:57,498 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 17:10:57,502 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 17:10:57,504 INFO] - [plugin init] ֲ: plugins.04_help -[2020-10-10 17:10:57,505 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 17:10:57,507 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 17:10:57,507 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 17:10:57,508 INFO] - [plugin base] ʼ: -[2020-10-10 17:10:57,509 INFO] - [MemoryTools] ʼ... -[2020-10-10 17:10:57,625 INFO] - [Ʒ] аıΪ: # -*- coding: utf-8 -*- -[2020-10-10 17:10:57,629 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 -[2020-10-10 17:10:59,246 INFO] - [Ʒ] Ϊ: -*-룺utf-8-*- -[2020-10-10 17:12:12,125 INFO] - [Ʒ] аıΪ: "https://github.com/MemoryD/MemoryTools" -[2020-10-10 17:12:12,126 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 -[2020-10-10 17:12:12,565 INFO] - [Ʒ] Ϊ: "HTTPS://GitHub.com/memory D/memory tools" -[2020-10-10 17:13:17,495 INFO] - [Ʒ] аıΪ: https://github.com/MemoryD/MemoryTools/releases -[2020-10-10 17:13:17,496 INFO] - [Ʒ] ıҪΪ: en, ռ: 1.0 -[2020-10-10 17:13:18,140 INFO] - [Ʒ] Ϊ: HTTPS://GitHub.com/memory D/memory tools/releases -[2020-10-10 17:15:41,938 INFO] - [Ʒ] аıΪ: ("־", None, self.open_log, True), -[2020-10-10 17:15:41,938 INFO] - [Ʒ] ıҪΪ: en, ռ: 0.75 -[2020-10-10 17:15:42,192 INFO] - [Ʒ] ԭһ£˲ʾ -[2020-10-10 17:16:08,824 INFO] - [MemoryTools] ˳ - -[2020-10-10 17:16:10,301 INFO] - [MemoryTools] -[2020-10-10 17:16:10,510 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 17:16:10,542 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 17:16:10,545 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 17:16:10,550 INFO] - [plugin init] ֲ: plugins.04_help -[2020-10-10 17:16:10,551 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 17:16:10,552 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 17:16:10,553 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 17:16:10,554 INFO] - [plugin base] ʼ: -[2020-10-10 17:16:10,555 INFO] - [MemoryTools] ʼ... -[2020-10-10 17:16:10,659 INFO] - [Ʒ] аıΪ: ("־", None, self.open_log, True), -[2020-10-10 17:16:10,662 INFO] - [Ʒ] ıҪΪ: en, ռ: 0.75 -[2020-10-10 17:16:12,868 INFO] - [Ʒ] ԭһ£˲ʾ -[2020-10-10 17:16:25,172 INFO] - [MemoryTools] ˳ - -[2020-10-10 17:16:27,036 INFO] - [MemoryTools] -[2020-10-10 17:16:27,236 INFO] - [plugin init] ֲ: plugins.01_copytrans -[2020-10-10 17:16:27,268 INFO] - [plugin init] ֲ: plugins.02_ocr -[2020-10-10 17:16:27,271 INFO] - [plugin init] ֲ: plugins.03_alert -[2020-10-10 17:16:27,276 INFO] - [plugin init] ֲ: plugins.04_help -[2020-10-10 17:16:27,277 INFO] - [plugin base] ʼ: Ʒ -[2020-10-10 17:16:27,278 INFO] - [plugin base] ʼ: OCRʶ -[2020-10-10 17:16:27,279 INFO] - [plugin base] ʼ: Ϣ -[2020-10-10 17:16:27,280 INFO] - [plugin base] ʼ: -[2020-10-10 17:16:27,281 INFO] - [MemoryTools] ʼ... -[2020-10-10 17:16:27,384 INFO] - [Ʒ] аıΪ: ("־", None, self.open_log, True), -[2020-10-10 17:16:27,387 INFO] - [Ʒ] ıҪΪ: en, ռ: 0.75 -[2020-10-10 17:16:29,641 INFO] - [Ʒ] ԭһ£˲ʾ -[2020-10-10 17:16:45,969 INFO] - [MemoryTools] ˳ - diff --git a/memorytools/plugins/config.json b/memorytools/plugins/config.json deleted file mode 100644 index f960ba2..0000000 --- a/memorytools/plugins/config.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "复制翻译": { - "is_trans": false, - "newline": false, - "strict": false, - "mode": "both", - "src": "en", - "dest": "zh-cn" - }, - "OCR识别": { - "is_ocr": false, - "newline": false, - "mode": "text" - }, - "休息提醒": { - "is_alert": false, - "alert_time": 30 - } -} \ No newline at end of file From 33a2522d374d4a6cdf7b4f7465ddb511cdfae100 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Sun, 11 Oct 2020 08:17:55 +0800 Subject: [PATCH 19/28] =?UTF-8?q?xjb=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + memorytools/globals.py | 4 +- memorytools/memorytools.spec | 38 +++++++++++++++++++ memorytools/plugins/__init__.py | 30 +++++++++++---- .../plugins/{03_alert => alert}/__init__.py | 0 .../plugins/{03_alert => alert}/alert.py | 13 ++++++- .../plugins/{03_alert => alert}/alertbox.py | 0 .../plugins/{03_alert => alert}/config.json | 2 +- memorytools/plugins/base.py | 20 +++++++--- .../{01_copytrans => copytrans}/__init__.py | 1 + .../{01_copytrans => copytrans}/config.json | 0 .../{01_copytrans => copytrans}/copytrans.py | 19 ++++++++-- .../{01_copytrans => copytrans}/transbox.py | 4 ++ .../plugins/{04_help => help}/__init__.py | 0 .../plugins/{04_help => help}/config.json | 0 memorytools/plugins/{04_help => help}/help.py | 3 +- .../plugins/{02_ocr => ocr}/__init__.py | 0 .../plugins/{02_ocr => ocr}/baiduOCR.py | 0 .../plugins/{02_ocr => ocr}/config.json | 0 memorytools/plugins/{02_ocr => ocr}/ocr.py | 14 ++++++- memorytools/plugins/{02_ocr => ocr}/ocrbox.py | 0 .../plugins/{02_ocr => ocr}/xueersiOCR.py | 0 memorytools/tools/logger.py | 4 +- 23 files changed, 129 insertions(+), 25 deletions(-) create mode 100644 memorytools/memorytools.spec rename memorytools/plugins/{03_alert => alert}/__init__.py (100%) rename memorytools/plugins/{03_alert => alert}/alert.py (87%) rename memorytools/plugins/{03_alert => alert}/alertbox.py (100%) rename memorytools/plugins/{03_alert => alert}/config.json (54%) rename memorytools/plugins/{01_copytrans => copytrans}/__init__.py (71%) rename memorytools/plugins/{01_copytrans => copytrans}/config.json (100%) rename memorytools/plugins/{01_copytrans => copytrans}/copytrans.py (92%) rename memorytools/plugins/{01_copytrans => copytrans}/transbox.py (89%) rename memorytools/plugins/{04_help => help}/__init__.py (100%) rename memorytools/plugins/{04_help => help}/config.json (100%) rename memorytools/plugins/{04_help => help}/help.py (88%) rename memorytools/plugins/{02_ocr => ocr}/__init__.py (100%) rename memorytools/plugins/{02_ocr => ocr}/baiduOCR.py (100%) rename memorytools/plugins/{02_ocr => ocr}/config.json (100%) rename memorytools/plugins/{02_ocr => ocr}/ocr.py (85%) rename memorytools/plugins/{02_ocr => ocr}/ocrbox.py (100%) rename memorytools/plugins/{02_ocr => ocr}/xueersiOCR.py (100%) diff --git a/.gitignore b/.gitignore index 6400050..3057bed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ dist/ build/ +*/dist/ +*/build/ memorytools.egg-info/ *.egg-info/ *.pyc diff --git a/memorytools/globals.py b/memorytools/globals.py index 30a79fe..2b14cac 100644 --- a/memorytools/globals.py +++ b/memorytools/globals.py @@ -20,13 +20,13 @@ class PATH: cwd = Path() plugins = cwd / 'plugins' - config = plugins / 'config.json' + config = cwd / 'config' icon = cwd / 'src' / 'icon' log = cwd / 'log' class TEXT: - hover = "Memory Tools v1.8.0" + hover = "Memory Tools v2.0.0 beta" alert = '你已经连续工作 %d 分钟了!是时候休息一下了!\ntip: 连续在电脑前工作太久容易脱发,得颈椎病,猝死。' diff --git a/memorytools/memorytools.spec b/memorytools/memorytools.spec new file mode 100644 index 0000000..fa4aac6 --- /dev/null +++ b/memorytools/memorytools.spec @@ -0,0 +1,38 @@ +# -*- mode: python ; coding: utf-8 -*- + +block_cipher = None + +py_files = ['globals.py', 'memorytools.py', '__init__.py', 'plugins\\base.py', 'plugins\\__init__.py', 'plugins\\alert\\alert.py', 'plugins\\alert\\alertbox.py', 'plugins\\alert\\__init__.py', 'plugins\\copytrans\\copytrans.py', 'plugins\\copytrans\\transbox.py', 'plugins\\copytrans\\__init__.py', 'plugins\\help\\help.py', 'plugins\\help\\__init__.py', 'plugins\\ocr\\baiduOCR.py', 'plugins\\ocr\\ocr.py', 'plugins\\ocr\\ocrbox.py', 'plugins\\ocr\\xueersiOCR.py', 'plugins\\ocr\\__init__.py', 'tools\\basebox.py', 'tools\\logger.py', 'tools\\utils.py', 'tools\\__init__.py', 'tools\\systray\\traybar.py', 'tools\\systray\\win32_adapter.py', 'tools\\systray\\__init__.py', 'tools\\systray\\__version__.py'] + +a = Analysis(py_files, + pathex=['C:\\Users\\Memory\\OneDrive\\code\\MemoryTools\\memorytools'], + binaries=[], + datas=[], + hiddenimports=[], + hookspath=[], + runtime_hooks=[], + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False) +pyz = PYZ(a.pure, a.zipped_data, + cipher=block_cipher) +exe = EXE(pyz, + a.scripts, + [], + exclude_binaries=True, + name='memorytools', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + console=True , icon='..\\src\\icon.ico') +coll = COLLECT(exe, + a.binaries, + a.zipfiles, + a.datas, + strip=False, + upx=True, + upx_exclude=[], + name='memorytools') diff --git a/memorytools/plugins/__init__.py b/memorytools/plugins/__init__.py index 0f54a1c..7e9d35a 100644 --- a/memorytools/plugins/__init__.py +++ b/memorytools/plugins/__init__.py @@ -3,14 +3,30 @@ from pathlib import Path from tools.logger import logger from .base import BasePlugin, change_config +from .alert import Alert +from .copytrans import CopyTrans +from .ocr import OCR +from .help import Help +# from setuptools import setup, find_packages + +plugin_list = [CopyTrans, OCR, Alert, Help] + + +# packages = find_packages() +# plugin_list = [] +# for package in packages: +# if package.startswith("plugins."): +# module = import_module(package) +# plugin_list.append(module.plugin) +# logger.info("[plugin init] 发现插件包: "+module.__name__) # 插件包所在的目录 -plugin_path = Path(__file__).parent +# plugin_path = Path(__file__).parent # 加载所有的插件包 -plugin_list = [] -for d in plugin_path.iterdir(): - if d.is_dir() and d.name != "__pycache__": - module = import_module("plugins." + d.name) - plugin_list.append(module.plugin) - logger.info("[plugin init] 发现插件包: "+module.__name__) +# plugin_list = [] +# for d in plugin_path.iterdir(): +# if d.is_dir() and d.name != "__pycache__": +# module = import_module("plugins." + d.name) +# plugin_list.append(module.plugin) +# logger.info("[plugin init] 发现插件包: "+module.__name__) diff --git a/memorytools/plugins/03_alert/__init__.py b/memorytools/plugins/alert/__init__.py similarity index 100% rename from memorytools/plugins/03_alert/__init__.py rename to memorytools/plugins/alert/__init__.py diff --git a/memorytools/plugins/03_alert/alert.py b/memorytools/plugins/alert/alert.py similarity index 87% rename from memorytools/plugins/03_alert/alert.py rename to memorytools/plugins/alert/alert.py index 55cffba..203d915 100644 --- a/memorytools/plugins/03_alert/alert.py +++ b/memorytools/plugins/alert/alert.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from time import time from .alertbox import AlertBox -from globals import TEXT, ICON +from globals import TEXT, ICON, PATH from tools.utils import is_check, is_pick from tools.logger import logger from plugins import BasePlugin, change_config @@ -10,8 +10,10 @@ class Alert(BasePlugin): def __init__(self, root) -> None: - config_path = Path(__file__).parent / "config.json" + # config_path = Path(__file__).parent / "config.json" + config_path = PATH.config / ("%s.json" % Path(__file__).stem) super(Alert, self).__init__("休息提醒", root, ICON.alert, config_path) + self.config = self.init_config() self.start_time = time() def create_menu(self): @@ -25,6 +27,13 @@ def create_menu(self): return menu_options + def create_default_config(self) -> dict: + config = { + "is_alert": True, + "alert_time": 90 + } + return config + @change_config def pause_alert(self, s): self.is_alert = not self.is_alert diff --git a/memorytools/plugins/03_alert/alertbox.py b/memorytools/plugins/alert/alertbox.py similarity index 100% rename from memorytools/plugins/03_alert/alertbox.py rename to memorytools/plugins/alert/alertbox.py diff --git a/memorytools/plugins/03_alert/config.json b/memorytools/plugins/alert/config.json similarity index 54% rename from memorytools/plugins/03_alert/config.json rename to memorytools/plugins/alert/config.json index 21b6219..664824e 100644 --- a/memorytools/plugins/03_alert/config.json +++ b/memorytools/plugins/alert/config.json @@ -1,4 +1,4 @@ { "is_alert": true, - "alert_time": 60 + "alert_time": 90 } \ No newline at end of file diff --git a/memorytools/plugins/base.py b/memorytools/plugins/base.py index 1ebf5df..66d593d 100644 --- a/memorytools/plugins/base.py +++ b/memorytools/plugins/base.py @@ -26,10 +26,9 @@ class BasePlugin(object): 所有插件的基类,提供插件的统一运行框架。 每个插件都以一个模块的形式存在,假设在一个插件名为 test,则可以: 1. 创建一个包为 plugins/test (文件夹名字随意) - 2. 包内至少 3 个文件: + 2. 包内至少 2 个文件: 2.1 __init__.py: 必须包含一个变量 plugin, 指向一个 BasePlugin 的子类 2.2 test.py(文件名随意):插件的主要运行代码,其中有一个类必须继承 BasePlugin,并写到 __init__.py 中 - 2.3 config.json:托盘菜单配置文件,里面的属性会被绑定到 BasePlugin 子类中 具体可以参阅plugins文件夹下面的几个插件。 """ def __init__(self, name: str, root, icon: str, config_path: Path): @@ -43,15 +42,18 @@ def __init__(self, name: str, root, icon: str, config_path: Path): self.root = root self.icon = icon self.config_path = config_path - self.config = self.init_config() logger.info("[plugin base] 初始化插件: " + self.name) def init_config(self): """ - 读取目录下的配置文件,并将属性绑定到类中 + 读取目录下的配置文件,并将属性绑定到类中, + 如果没有配置文件,则使用默认的配置 """ - config = self.config_path.read_text(encoding="utf-8") - config = EasyDict(json.loads(config)) + if not self.config_path.exists(): + config = self.create_default_config() + else: + config = self.config_path.read_text(encoding="utf-8") + config = json.loads(config) for attr, value in config.items(): self.__setattr__(attr, value) @@ -69,6 +71,12 @@ def save_config(self): data = json.dumps(self.config, indent=4, ensure_ascii=False) self.config_path.write_text(data, encoding="utf-8") + def create_default_config(self) -> dict: + """ + 返回默认的配置 + """ + return {} + def init_menu(self) -> tuple: """ 入口菜单项 diff --git a/memorytools/plugins/01_copytrans/__init__.py b/memorytools/plugins/copytrans/__init__.py similarity index 71% rename from memorytools/plugins/01_copytrans/__init__.py rename to memorytools/plugins/copytrans/__init__.py index 1e7c4ff..ef02c3a 100644 --- a/memorytools/plugins/01_copytrans/__init__.py +++ b/memorytools/plugins/copytrans/__init__.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- from .copytrans import CopyTrans +from .transbox import TransBox plugin = CopyTrans diff --git a/memorytools/plugins/01_copytrans/config.json b/memorytools/plugins/copytrans/config.json similarity index 100% rename from memorytools/plugins/01_copytrans/config.json rename to memorytools/plugins/copytrans/config.json diff --git a/memorytools/plugins/01_copytrans/copytrans.py b/memorytools/plugins/copytrans/copytrans.py similarity index 92% rename from memorytools/plugins/01_copytrans/copytrans.py rename to memorytools/plugins/copytrans/copytrans.py index 7073258..a3287ac 100644 --- a/memorytools/plugins/01_copytrans/copytrans.py +++ b/memorytools/plugins/copytrans/copytrans.py @@ -7,7 +7,7 @@ from tools.logger import logger from requests.exceptions import ConnectionError from plugins import BasePlugin, change_config -from globals import ICON +from globals import ICON, PATH class CopyTrans(BasePlugin): @@ -15,9 +15,11 @@ class CopyTrans(BasePlugin): 一个复制翻译的插件,调用谷歌翻译的接口翻译剪切板中的文本 """ def __init__(self, root) -> None: - config_path = Path(__file__).parent / "config.json" + # config_path = Path(__file__).parent / "config.json" + config_path = PATH.config / ("%s.json" % Path(__file__).stem) super(CopyTrans, self).__init__("复制翻译", root, ICON.trans, config_path) - self.last = '' # 记录上次的剪切板内容 + self.config = self.init_config() + self.last = '' # 记录上次的剪切板内容 self.translator = self.get_translator() # 获得翻译接口 def create_menu(self) -> tuple: @@ -32,6 +34,17 @@ def create_menu(self) -> tuple: return menu_options + def create_default_config(self) -> dict: + config = { + "is_trans": True, + "newline": False, + "strict": False, + "mode": "both", + "src": "en", + "dest": "zh-cn" + } + return config + @classmethod def get_translator(cls): return Translator(service_urls=['translate.google.cn']) diff --git a/memorytools/plugins/01_copytrans/transbox.py b/memorytools/plugins/copytrans/transbox.py similarity index 89% rename from memorytools/plugins/01_copytrans/transbox.py rename to memorytools/plugins/copytrans/transbox.py index 0354c1b..5093fbb 100644 --- a/memorytools/plugins/01_copytrans/transbox.py +++ b/memorytools/plugins/copytrans/transbox.py @@ -15,6 +15,10 @@ def retrans(self): 根据用户的更改重新进行翻译 """ sentence = self.src_text.get("1.0", END) + sentence = self.copy_trans.remove_newline(sentence) + self.src_text.delete("1.0", END) + self.src_text.insert(END, sentence) + text = self.copy_trans.trans_text(sentence) self.textbox.delete("1.0", END) self.textbox.insert(END, text) diff --git a/memorytools/plugins/04_help/__init__.py b/memorytools/plugins/help/__init__.py similarity index 100% rename from memorytools/plugins/04_help/__init__.py rename to memorytools/plugins/help/__init__.py diff --git a/memorytools/plugins/04_help/config.json b/memorytools/plugins/help/config.json similarity index 100% rename from memorytools/plugins/04_help/config.json rename to memorytools/plugins/help/config.json diff --git a/memorytools/plugins/04_help/help.py b/memorytools/plugins/help/help.py similarity index 88% rename from memorytools/plugins/04_help/help.py rename to memorytools/plugins/help/help.py index 1e29340..aa1d4f5 100644 --- a/memorytools/plugins/04_help/help.py +++ b/memorytools/plugins/help/help.py @@ -8,8 +8,9 @@ class Help(BasePlugin): def __init__(self, root) -> None: - config_path = Path(__file__).parent / "config.json" + config_path = PATH.config / ("%s.json" % Path(__file__).stem) super(Help, self).__init__("帮助", root, ICON.about, config_path) + self.config = self.init_config() def about(self, s): """ diff --git a/memorytools/plugins/02_ocr/__init__.py b/memorytools/plugins/ocr/__init__.py similarity index 100% rename from memorytools/plugins/02_ocr/__init__.py rename to memorytools/plugins/ocr/__init__.py diff --git a/memorytools/plugins/02_ocr/baiduOCR.py b/memorytools/plugins/ocr/baiduOCR.py similarity index 100% rename from memorytools/plugins/02_ocr/baiduOCR.py rename to memorytools/plugins/ocr/baiduOCR.py diff --git a/memorytools/plugins/02_ocr/config.json b/memorytools/plugins/ocr/config.json similarity index 100% rename from memorytools/plugins/02_ocr/config.json rename to memorytools/plugins/ocr/config.json diff --git a/memorytools/plugins/02_ocr/ocr.py b/memorytools/plugins/ocr/ocr.py similarity index 85% rename from memorytools/plugins/02_ocr/ocr.py rename to memorytools/plugins/ocr/ocr.py index 972f629..990a64f 100644 --- a/memorytools/plugins/02_ocr/ocr.py +++ b/memorytools/plugins/ocr/ocr.py @@ -5,15 +5,17 @@ from PIL import Image, ImageGrab, ImageDraw from .ocrbox import OcrBox from tools.logger import logger -from globals import BAIDU_ACCOUNTS, XUEERSI_ACCOUNTS, ICON +from globals import BAIDU_ACCOUNTS, XUEERSI_ACCOUNTS, ICON, PATH from tools.utils import is_check, is_pick, get_rect, Color, copy_clip from plugins import BasePlugin, change_config class OCR(BasePlugin): def __init__(self, root): - config_path = Path(__file__).parent / "config.json" + # config_path = Path(__file__).parent / "config.json" + config_path = PATH.config / ("%s.json" % Path(__file__).stem) super(OCR, self).__init__("OCR识别", root, ICON.ocr, config_path) + self.config = self.init_config() self.text_ocr = BaiduOCR(BAIDU_ACCOUNTS) self.math_ocr = LatexOCR(XUEERSI_ACCOUNTS) @@ -27,6 +29,14 @@ def create_menu(self) -> tuple: return menu_options + def create_default_config(self) -> dict: + config = { + "is_ocr": True, + "newline": False, + "mode": "text" + } + return config + @change_config def pause_ocr(self, s): self.is_ocr = not self.is_ocr diff --git a/memorytools/plugins/02_ocr/ocrbox.py b/memorytools/plugins/ocr/ocrbox.py similarity index 100% rename from memorytools/plugins/02_ocr/ocrbox.py rename to memorytools/plugins/ocr/ocrbox.py diff --git a/memorytools/plugins/02_ocr/xueersiOCR.py b/memorytools/plugins/ocr/xueersiOCR.py similarity index 100% rename from memorytools/plugins/02_ocr/xueersiOCR.py rename to memorytools/plugins/ocr/xueersiOCR.py diff --git a/memorytools/tools/logger.py b/memorytools/tools/logger.py index 22e8859..d7edcda 100644 --- a/memorytools/tools/logger.py +++ b/memorytools/tools/logger.py @@ -3,6 +3,7 @@ import logging import logging.handlers from sys import stdout +from pathlib import Path class Logger(object): @@ -20,6 +21,7 @@ def __init__(self, log_level=logging.INFO, log_file=None): self.logger.addHandler(ch) if log_file: + log_file.parent.mkdir(parents=True, exist_ok=True) fh = logging.handlers.TimedRotatingFileHandler(log_file, when='D', interval=1, backupCount=30) fh.setLevel(log_level) fh.setFormatter(formatter) @@ -29,7 +31,7 @@ def get_logger(self): return self.logger -logger = Logger(log_file="log/memorytools.log").get_logger() +logger = Logger(log_file=Path("log/memorytools.log")).get_logger() if __name__ == '__main__': # logger = Logger().get_logger() From 31fa7f57e325cb98938854527e95fc831f8b6719 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Sun, 11 Oct 2020 10:44:23 +0800 Subject: [PATCH 20/28] =?UTF-8?q?=E6=9B=B4=E6=94=B9readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE | 7 +++++++ README.md | 36 ++++++++++++++++++++++++++------ memorytools/__init__.py | 4 ++-- memorytools/count_code.py | 25 ++++++++++++++++++++++ memorytools/globals.py | 1 + memorytools/memorytools.spec | 6 ++++-- memorytools/toexe.cmd | 1 + memorytools/tools/__main__.py | 5 +++++ setup.py | 39 +++++++++++++++++++++++++++++++++++ 9 files changed, 114 insertions(+), 10 deletions(-) create mode 100644 LICENSE create mode 100644 memorytools/count_code.py create mode 100644 memorytools/toexe.cmd create mode 100644 memorytools/tools/__main__.py create mode 100644 setup.py diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6973e4d --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +Copyright <2020> + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index c501815..3114e8f 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,34 @@ -## Memory Tools V1.6.0 +## Memory Tools V2.0.0 Beta -> 2020/3/26 更新 +> 2020/10/11 更新 --- -#### 软件功能 +### 0. 前言 + +这软件到现在已经快两年了,最初只是想做一个软件帮我去除复制的PDF文本中的换行符,后面又想着直接翻译更省事。之后又觉得加个托盘图标比较酷炫,就想方设法加了一个托盘图标,但是这也使得软件只能在win下运行了。到今年疫情在家无事,又重写了整个软件,优化了外观,并且加入了OCR的接口。 + +这学期给实验室一些人用发现了挺多bug,刚好这两天因为运动损伤待在宿舍里,就重构了代码,将各个功能都封装成包,以后往里面加东西就会变得非常方便了。 + +### 1. 运行 + +正如前面所说,这个软件仅支持在windows下面运行。 + +- **使用exe** + + 为了方便给别人使用,我使用pyinstaller进行了打包,可以在 [MemortTools Release](https://github.com/MemoryD/MemoryTools/releases) 页面进行下载。解压后运行其中的 `memorytools.exe` 即可。 + +- **使用源码** + + ```sh + git clone https://github.com/MemoryD/MemoryTools + cd MemoryTools + pip install -r requirements.txt + cd memorytools + python memorytools.py + ``` + +### 2. 软件功能 - **复制翻译**:翻译剪切板的文本,并弹框显示结果。 - **中文-->英文**:中文翻译成英文,如果复制的文本英文的比例过高,则不会翻译。 @@ -15,7 +39,7 @@ - **OCR识别**:对剪切板中的图片进行OCR识别,并弹框显示。 - **识别:文本**:识别普通的文本。 - - **识别:公式**:可以识别公式,并转换成 Latex 代码。(准确率emmm...) + - **识别:公式**:可以识别公式,并转换成 Latex 代码。 - **去除换行**:是否去除识别后文本中的换行。识别公式时,此项不起作用。 - **休息提醒**:在你工作一段时间以后,提醒你该休息了。 @@ -23,7 +47,7 @@ --- -#### 软件说明 +### 3. 软件说明 1. 每次退出会保存程序的配置,下次启动时自动载入。 2. 复制翻译使用谷歌翻译的接口。 @@ -34,7 +58,7 @@ --- -#### 关于作者 +### 关于作者 1. 作者:Memory 2. 邮箱:memory_d@foxmail.com \ No newline at end of file diff --git a/memorytools/__init__.py b/memorytools/__init__.py index edf6401..b484739 100644 --- a/memorytools/__init__.py +++ b/memorytools/__init__.py @@ -1,11 +1,11 @@ ''' @name: __init__ @author: Memory -@date: 2020/03/20 +@date: 2020/10/11 ''' __title__ = 'memorytools' -__version__ = '1.6.1' +__version__ = '2.0.0' __author__ = 'Memory' __copyright__ = 'Copyright 2020 Memory' diff --git a/memorytools/count_code.py b/memorytools/count_code.py new file mode 100644 index 0000000..a71e439 --- /dev/null +++ b/memorytools/count_code.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +from pathlib import Path + + +def count_code(cwd: Path, count: dict): + for py in cwd.glob("*.py"): + count[str(py)] = len(py.read_text(encoding="utf-8").split('\n')) + + for p in cwd.iterdir(): + if p.is_dir(): + count_code(p, count) + + return count + +all_py = [] +count = count_code(Path(), {}) +total = 0 +for py, line in count.items(): + total += line + print(py, line) + +print(total) +print(list(count.keys())) + + diff --git a/memorytools/globals.py b/memorytools/globals.py index 2b14cac..83f68bf 100644 --- a/memorytools/globals.py +++ b/memorytools/globals.py @@ -23,6 +23,7 @@ class PATH: config = cwd / 'config' icon = cwd / 'src' / 'icon' log = cwd / 'log' + config.mkdir(parents=True, exist_ok=True) class TEXT: diff --git a/memorytools/memorytools.spec b/memorytools/memorytools.spec index fa4aac6..6c3743f 100644 --- a/memorytools/memorytools.spec +++ b/memorytools/memorytools.spec @@ -2,7 +2,9 @@ block_cipher = None -py_files = ['globals.py', 'memorytools.py', '__init__.py', 'plugins\\base.py', 'plugins\\__init__.py', 'plugins\\alert\\alert.py', 'plugins\\alert\\alertbox.py', 'plugins\\alert\\__init__.py', 'plugins\\copytrans\\copytrans.py', 'plugins\\copytrans\\transbox.py', 'plugins\\copytrans\\__init__.py', 'plugins\\help\\help.py', 'plugins\\help\\__init__.py', 'plugins\\ocr\\baiduOCR.py', 'plugins\\ocr\\ocr.py', 'plugins\\ocr\\ocrbox.py', 'plugins\\ocr\\xueersiOCR.py', 'plugins\\ocr\\__init__.py', 'tools\\basebox.py', 'tools\\logger.py', 'tools\\utils.py', 'tools\\__init__.py', 'tools\\systray\\traybar.py', 'tools\\systray\\win32_adapter.py', 'tools\\systray\\__init__.py', 'tools\\systray\\__version__.py'] +# py_files = ['memorytools.py', 'globals.py', '__init__.py', 'plugins\\base.py', 'plugins\\__init__.py', 'plugins\\alert\\alert.py', 'plugins\\alert\\alertbox.py', 'plugins\\alert\\__init__.py', 'plugins\\copytrans\\copytrans.py', 'plugins\\copytrans\\transbox.py', 'plugins\\copytrans\\__init__.py', 'plugins\\help\\help.py', 'plugins\\help\\__init__.py', 'plugins\\ocr\\baiduOCR.py', 'plugins\\ocr\\ocr.py', 'plugins\\ocr\\ocrbox.py', 'plugins\\ocr\\xueersiOCR.py', 'plugins\\ocr\\__init__.py', 'tools\\basebox.py', 'tools\\logger.py', 'tools\\utils.py', 'tools\\__init__.py', 'tools\\systray\\traybar.py', 'tools\\systray\\win32_adapter.py', 'tools\\systray\\__init__.py', 'tools\\systray\\__version__.py'] + +py_files = ['memorytools.py', ] a = Analysis(py_files, pathex=['C:\\Users\\Memory\\OneDrive\\code\\MemoryTools\\memorytools'], @@ -27,7 +29,7 @@ exe = EXE(pyz, bootloader_ignore_signals=False, strip=False, upx=True, - console=True , icon='..\\src\\icon.ico') + console=False , icon='..\\src\\icon.ico') coll = COLLECT(exe, a.binaries, a.zipfiles, diff --git a/memorytools/toexe.cmd b/memorytools/toexe.cmd new file mode 100644 index 0000000..39a8c79 --- /dev/null +++ b/memorytools/toexe.cmd @@ -0,0 +1 @@ +pyinstaller memorytools.py -i ..\src\icon.ico --upx-dir ..\upx-3.95-win64 \ No newline at end of file diff --git a/memorytools/tools/__main__.py b/memorytools/tools/__main__.py new file mode 100644 index 0000000..4450028 --- /dev/null +++ b/memorytools/tools/__main__.py @@ -0,0 +1,5 @@ +from pathlib import Path + +p = Path().absolute() + +print(p) diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..35a163a --- /dev/null +++ b/setup.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- + +from __future__ import print_function +from setuptools import setup, find_packages +import memorytools + +with open("README.md", "r", encoding='utf-8') as fh: + long_description = fh.read() + +setup( + name="memorytools", + version=memorytools.__version__, + author="Memory", + author_email="memory_d@foxmail.com", + description="some useful tools", + long_description=long_description, + long_description_content_type="text/markdown", + license="MIT", + url="https://github.com/MemoryD/MemoryTools", + packages=find_packages(), + install_requires=[ + "pillow", + "baidu-aip", + "pyperclip", + "googletransx", + "easydict", + ], + classifiers=[ + "Topic :: Software Development :: Libraries :: Python Modules", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + 'Programming Language :: Python :: Implementation :: CPython', + ], +) From ea4df8ef78764a1a35623c91a8d76cbf64d5c2d3 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Sun, 11 Oct 2020 11:10:28 +0800 Subject: [PATCH 21/28] v2.0.0 beta --- memorytools/__init__.py | 4 ++-- memorytools/count_code.py | 10 ++++++-- memorytools/globals.py | 6 +++++ memorytools/memorytools.py | 10 +++++--- memorytools/plugins/__init__.py | 27 ++++++++++------------ memorytools/plugins/alert/__init__.py | 6 ++++- memorytools/plugins/alert/alert.py | 6 +++++ memorytools/plugins/alert/alertbox.py | 6 +++++ memorytools/plugins/base.py | 7 +++++- memorytools/plugins/copytrans/__init__.py | 6 ++++- memorytools/plugins/copytrans/copytrans.py | 7 +++++- memorytools/plugins/copytrans/transbox.py | 6 +++++ memorytools/plugins/help/__init__.py | 7 ++++++ memorytools/plugins/help/help.py | 6 +++++ memorytools/plugins/ocr/__init__.py | 6 ++++- memorytools/plugins/ocr/baiduOCR.py | 6 +++++ memorytools/plugins/ocr/ocr.py | 6 +++++ memorytools/plugins/ocr/ocrbox.py | 6 +++++ memorytools/plugins/ocr/xueersiOCR.py | 6 +++++ memorytools/tools/__init__.py | 5 ++++ memorytools/tools/basebox.py | 4 ++-- memorytools/tools/logger.py | 7 +++++- memorytools/tools/utils.py | 7 +++++- 23 files changed, 136 insertions(+), 31 deletions(-) diff --git a/memorytools/__init__.py b/memorytools/__init__.py index b484739..6a6a2cb 100644 --- a/memorytools/__init__.py +++ b/memorytools/__init__.py @@ -1,8 +1,8 @@ -''' +""" @name: __init__ @author: Memory @date: 2020/10/11 -''' +""" __title__ = 'memorytools' diff --git a/memorytools/count_code.py b/memorytools/count_code.py index a71e439..4c13d4d 100644 --- a/memorytools/count_code.py +++ b/memorytools/count_code.py @@ -1,4 +1,11 @@ # -*- coding: utf-8 -*- +""" +@name: count_code +@author: Memory +@date: 2020/10/11 +@description: 统计项目中的py代码行数 +""" + from pathlib import Path @@ -12,7 +19,7 @@ def count_code(cwd: Path, count: dict): return count -all_py = [] + count = count_code(Path(), {}) total = 0 for py, line in count.items(): @@ -20,6 +27,5 @@ def count_code(cwd: Path, count: dict): print(py, line) print(total) -print(list(count.keys())) diff --git a/memorytools/globals.py b/memorytools/globals.py index 83f68bf..4042c16 100644 --- a/memorytools/globals.py +++ b/memorytools/globals.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +""" +@name: globals +@author: Memory +@date: 2020/10/11 +@description: 一些全局变量的定义 +""" from string import punctuation from easydict import EasyDict from pathlib import Path diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index e953713..0b43824 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -1,6 +1,10 @@ # -*- coding: utf-8 -*- - -from webbrowser import open as open_web +""" +@name: memorytools +@author: Memory +@date: 2020/10/11 +@description: 项目的入口文件 +""" from time import sleep from tools.logger import logger @@ -52,7 +56,6 @@ def bye(self, s: SysTrayIcon): 退出程序 """ self.end = True - logger.info("[MemoryTools] 退出程序\n") def run(self): """ @@ -67,6 +70,7 @@ def run(self): plugin.start() except Exception as e: logger.error("[MemoryTools] %s" % e) + logger.info("[MemoryTools] 退出程序\n") if __name__ == '__main__': diff --git a/memorytools/plugins/__init__.py b/memorytools/plugins/__init__.py index 7e9d35a..60648cd 100644 --- a/memorytools/plugins/__init__.py +++ b/memorytools/plugins/__init__.py @@ -1,17 +1,25 @@ # -*- coding: utf-8 -*- -from importlib import import_module -from pathlib import Path -from tools.logger import logger +""" +@file: __init__ +@author: Memory +@date: 2020/10/11 +@description: plugin的初始化文件,用于创建一个plugin_list +""" from .base import BasePlugin, change_config from .alert import Alert from .copytrans import CopyTrans from .ocr import OCR from .help import Help -# from setuptools import setup, find_packages + plugin_list = [CopyTrans, OCR, Alert, Help] +# 以下代码是用于自动寻找插件包的,但是如果使用pyinstaller打包的话, +# 需要将plugins文件夹拷进去才能正常工作,因此暂不使用 +# from importlib import import_module +# from tools.logger import logger +# from setuptools import find_packages # packages = find_packages() # plugin_list = [] # for package in packages: @@ -19,14 +27,3 @@ # module = import_module(package) # plugin_list.append(module.plugin) # logger.info("[plugin init] 发现插件包: "+module.__name__) - -# 插件包所在的目录 -# plugin_path = Path(__file__).parent - -# 加载所有的插件包 -# plugin_list = [] -# for d in plugin_path.iterdir(): -# if d.is_dir() and d.name != "__pycache__": -# module = import_module("plugins." + d.name) -# plugin_list.append(module.plugin) -# logger.info("[plugin init] 发现插件包: "+module.__name__) diff --git a/memorytools/plugins/alert/__init__.py b/memorytools/plugins/alert/__init__.py index dfa4353..bd488d3 100644 --- a/memorytools/plugins/alert/__init__.py +++ b/memorytools/plugins/alert/__init__.py @@ -1,5 +1,9 @@ # -*- coding: utf-8 -*- - +""" +@file: __init__ +@author: Memory +@date: 2020/10/11 +""" from .alert import Alert plugin = Alert diff --git a/memorytools/plugins/alert/alert.py b/memorytools/plugins/alert/alert.py index 203d915..d9db44d 100644 --- a/memorytools/plugins/alert/alert.py +++ b/memorytools/plugins/alert/alert.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +""" +@file: alert +@author: Memory +@date: 2020/10/11 +@description: 用于休息提醒 +""" from time import time from .alertbox import AlertBox from globals import TEXT, ICON, PATH diff --git a/memorytools/plugins/alert/alertbox.py b/memorytools/plugins/alert/alertbox.py index 6ba4d8f..8e70059 100644 --- a/memorytools/plugins/alert/alertbox.py +++ b/memorytools/plugins/alert/alertbox.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +""" +@file: alertbox +@author: Memory +@date: 2020/10/11 +@description: 休息提醒的弹出框定义 +""" from tkinter.ttk import Label from tools.basebox import BaseBox diff --git a/memorytools/plugins/base.py b/memorytools/plugins/base.py index 66d593d..947978e 100644 --- a/memorytools/plugins/base.py +++ b/memorytools/plugins/base.py @@ -1,7 +1,12 @@ # -*- coding: utf-8 -*- +""" +@file: base +@author: Memory +@date: 2020/10/11 +@description: 所有插件的基类,提供插件的统一运行框架。 +""" import json from pathlib import Path -from easydict import EasyDict from tools.logger import logger diff --git a/memorytools/plugins/copytrans/__init__.py b/memorytools/plugins/copytrans/__init__.py index ef02c3a..08554c5 100644 --- a/memorytools/plugins/copytrans/__init__.py +++ b/memorytools/plugins/copytrans/__init__.py @@ -1,5 +1,9 @@ # -*- coding: utf-8 -*- - +""" +@file: __init__ +@author: Memory +@date: 2020/10/11 +""" from .copytrans import CopyTrans from .transbox import TransBox diff --git a/memorytools/plugins/copytrans/copytrans.py b/memorytools/plugins/copytrans/copytrans.py index a3287ac..8b42b32 100644 --- a/memorytools/plugins/copytrans/copytrans.py +++ b/memorytools/plugins/copytrans/copytrans.py @@ -1,5 +1,10 @@ # -*- coding: utf-8 -*- - +""" +@file: copytrans +@author: Memory +@date: 2020/10/11 +@description: 复制翻译插件的定义 +""" from pathlib import Path from .transbox import TransBox from googletransx import Translator diff --git a/memorytools/plugins/copytrans/transbox.py b/memorytools/plugins/copytrans/transbox.py index 5093fbb..71820a9 100644 --- a/memorytools/plugins/copytrans/transbox.py +++ b/memorytools/plugins/copytrans/transbox.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +""" +@file: basebox +@author: Memory +@date: 2020/10/11 +@description: 复制翻译的弹出框 +""" from tkinter.scrolledtext import ScrolledText from tools.basebox import BaseBox, END from tools.utils import get_text_line diff --git a/memorytools/plugins/help/__init__.py b/memorytools/plugins/help/__init__.py index 2698908..462f6da 100644 --- a/memorytools/plugins/help/__init__.py +++ b/memorytools/plugins/help/__init__.py @@ -1,3 +1,10 @@ +# -*- coding: utf-8 -*- +""" +@file: __init__ +@author: Memory +@date: 2020/10/11 +""" + from .help import Help plugin = Help diff --git a/memorytools/plugins/help/help.py b/memorytools/plugins/help/help.py index aa1d4f5..55110df 100644 --- a/memorytools/plugins/help/help.py +++ b/memorytools/plugins/help/help.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +""" +@file: help +@author: Memory +@date: 2020/10/11 +@description: 帮助插件的定义 +""" from os import startfile from pathlib import Path from webbrowser import open as open_web diff --git a/memorytools/plugins/ocr/__init__.py b/memorytools/plugins/ocr/__init__.py index e3d38d1..952a80a 100644 --- a/memorytools/plugins/ocr/__init__.py +++ b/memorytools/plugins/ocr/__init__.py @@ -1,5 +1,9 @@ # -*- coding: utf-8 -*- - +""" +@file: __init__ +@author: Memory +@date: 2020/10/11 +""" from .baiduOCR import BaiduOCR from .xueersiOCR import LatexOCR from .ocr import OCR diff --git a/memorytools/plugins/ocr/baiduOCR.py b/memorytools/plugins/ocr/baiduOCR.py index be1e472..1f82242 100644 --- a/memorytools/plugins/ocr/baiduOCR.py +++ b/memorytools/plugins/ocr/baiduOCR.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +""" +@file: baiduOCR +@author: Memory +@date: 2020/10/11 +@description: 百度OCR的接口 +""" from aip import AipOcr from PIL import Image from tools.utils import pil2bytes diff --git a/memorytools/plugins/ocr/ocr.py b/memorytools/plugins/ocr/ocr.py index 990a64f..d6d09be 100644 --- a/memorytools/plugins/ocr/ocr.py +++ b/memorytools/plugins/ocr/ocr.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +""" +@file: ocr +@author: Memory +@date: 2020/10/11 +@description: ocr插件的定义 +""" from pathlib import Path from . import BaiduOCR from . import LatexOCR diff --git a/memorytools/plugins/ocr/ocrbox.py b/memorytools/plugins/ocr/ocrbox.py index dda5d51..893ee8a 100644 --- a/memorytools/plugins/ocr/ocrbox.py +++ b/memorytools/plugins/ocr/ocrbox.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +""" +@file: ocrbox +@author: Memory +@date: 2020/10/11 +@description: ocr弹出框的定义 +""" from tkinter import Label, END from tkinter.scrolledtext import ScrolledText from PIL import ImageTk diff --git a/memorytools/plugins/ocr/xueersiOCR.py b/memorytools/plugins/ocr/xueersiOCR.py index efe58f0..d323073 100644 --- a/memorytools/plugins/ocr/xueersiOCR.py +++ b/memorytools/plugins/ocr/xueersiOCR.py @@ -1,4 +1,10 @@ # -*- coding: utf-8 -*- +""" +@file: xueersiOCR +@author: Memory +@date: 2020/10/11 +@description: 学而思OCR的接口 +""" from time import sleep, time from random import randint, choice from PIL import Image diff --git a/memorytools/tools/__init__.py b/memorytools/tools/__init__.py index e69de29..6cf1059 100644 --- a/memorytools/tools/__init__.py +++ b/memorytools/tools/__init__.py @@ -0,0 +1,5 @@ +""" +@name: __init__ +@author: Memory +@date: 2020/10/11 +""" \ No newline at end of file diff --git a/memorytools/tools/basebox.py b/memorytools/tools/basebox.py index f2f2d3a..ef72b54 100644 --- a/memorytools/tools/basebox.py +++ b/memorytools/tools/basebox.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- """ -@file: basebox.py +@file: basebox @author: Memory -@date: 2020/3/23 +@date: 2020/10/11 @description: 自定义弹出框的基类,可以在插件中调用 """ diff --git a/memorytools/tools/logger.py b/memorytools/tools/logger.py index d7edcda..cac6ff3 100644 --- a/memorytools/tools/logger.py +++ b/memorytools/tools/logger.py @@ -1,5 +1,10 @@ # -*- coding: utf-8 -*- - +""" +@file: logger +@author: Memory +@date: 2020/10/11 +@description: 自定义一个日志生成器 +""" import logging import logging.handlers from sys import stdout diff --git a/memorytools/tools/utils.py b/memorytools/tools/utils.py index cfbc7ad..f1afdbe 100644 --- a/memorytools/tools/utils.py +++ b/memorytools/tools/utils.py @@ -1,5 +1,10 @@ # -*- coding: utf-8 -*- - +""" +@file: utils +@author: Memory +@date: 2020/10/11 +@description: 在项目中用到的一些方法定义 +""" import os import re import pyperclip From 3b9481d0fc622872f566eb6cb245c2b2c81bc221 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Mon, 12 Oct 2020 08:53:09 +0800 Subject: [PATCH 22/28] =?UTF-8?q?=E5=B0=8F=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重新翻译时,加入了等候语 --- memorytools/globals.py | 2 +- memorytools/memorytools.py | 5 ++++- memorytools/plugins/copytrans/transbox.py | 18 +++++++++++------- memorytools/toexe.cmd | 1 - memorytools/tools/__main__.py | 5 ----- 5 files changed, 16 insertions(+), 15 deletions(-) delete mode 100644 memorytools/toexe.cmd delete mode 100644 memorytools/tools/__main__.py diff --git a/memorytools/globals.py b/memorytools/globals.py index 4042c16..00d9891 100644 --- a/memorytools/globals.py +++ b/memorytools/globals.py @@ -33,7 +33,7 @@ class PATH: class TEXT: - hover = "Memory Tools v2.0.0 beta" + hover = "Memory Tools" alert = '你已经连续工作 %d 分钟了!是时候休息一下了!\ntip: 连续在电脑前工作太久容易脱发,得颈椎病,猝死。' diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index 0b43824..4f0f2fb 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -20,10 +20,13 @@ class MemoryTool(object): 程序的入口类 """ + version = "v2.0.0 beta" + def __init__(self): self.plugins = [plugin(self) for plugin in plugin_list] - self.systray = SysTrayIcon(ICON.icon, TEXT.hover, self.create_menu(), + hover_text = "MemoryTools " + self.version + self.systray = SysTrayIcon(ICON.icon, hover_text, self.create_menu(), on_quit=self.bye, default_menu_index=1, exit_ico=ICON.exit ) diff --git a/memorytools/plugins/copytrans/transbox.py b/memorytools/plugins/copytrans/transbox.py index 71820a9..a03f90f 100644 --- a/memorytools/plugins/copytrans/transbox.py +++ b/memorytools/plugins/copytrans/transbox.py @@ -16,31 +16,35 @@ def __init__(self, title="翻译结果", copy_trans=None): super(TransBox, self).__init__(buttons, title) self.copy_trans = copy_trans + def set_text(self, textbox, text): + textbox.delete("1.0", END) + textbox.insert(END, text) + def retrans(self): """ 根据用户的更改重新进行翻译 """ sentence = self.src_text.get("1.0", END) sentence = self.copy_trans.remove_newline(sentence) - self.src_text.delete("1.0", END) - self.src_text.insert(END, sentence) + + self.set_text(self.src_text, sentence) + self.set_text(self.dest_text, "翻译中,请稍候...") text = self.copy_trans.trans_text(sentence) - self.textbox.delete("1.0", END) - self.textbox.insert(END, text) + self.set_text(self.dest_text, text) def show(self, src: str, dest: str): h1 = min(10, max(5, get_text_line(src) + 1)) h2 = min(10, max(5, get_text_line(dest) + 1)) self.src_text = ScrolledText(self, height=h1, background='#ffffff', font=("微软雅黑", 11)) - self.textbox = ScrolledText(self, height=h2, background='#ffffff', font=("微软雅黑", 11)) + self.dest_text = ScrolledText(self, height=h2, background='#ffffff', font=("微软雅黑", 11)) self.src_text.insert(END, str(src)) self.src_text.config() - self.textbox.insert(END, str(dest)) + self.dest_text.insert(END, str(dest)) self.src_text.pack(side='top', padx=10, pady=10) - self.textbox.pack(side='top', padx=10, pady=10) + self.dest_text.pack(side='top', padx=10, pady=10) self.start() diff --git a/memorytools/toexe.cmd b/memorytools/toexe.cmd deleted file mode 100644 index 39a8c79..0000000 --- a/memorytools/toexe.cmd +++ /dev/null @@ -1 +0,0 @@ -pyinstaller memorytools.py -i ..\src\icon.ico --upx-dir ..\upx-3.95-win64 \ No newline at end of file diff --git a/memorytools/tools/__main__.py b/memorytools/tools/__main__.py deleted file mode 100644 index 4450028..0000000 --- a/memorytools/tools/__main__.py +++ /dev/null @@ -1,5 +0,0 @@ -from pathlib import Path - -p = Path().absolute() - -print(p) From cb3215cb33ed44fc190826a9fbea53a0dd5b03c5 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Mon, 12 Oct 2020 14:19:00 +0800 Subject: [PATCH 23/28] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- memorytools/plugins/alert/alert.py | 8 ++++++-- memorytools/plugins/copytrans/copytrans.py | 3 +-- memorytools/plugins/help/help.py | 2 +- memorytools/plugins/ocr/ocr.py | 3 +-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/memorytools/plugins/alert/alert.py b/memorytools/plugins/alert/alert.py index d9db44d..0c1df73 100644 --- a/memorytools/plugins/alert/alert.py +++ b/memorytools/plugins/alert/alert.py @@ -14,10 +14,14 @@ from pathlib import Path +class BaseAlert(BasePlugin): + def __init__(self): + pass + + class Alert(BasePlugin): def __init__(self, root) -> None: - # config_path = Path(__file__).parent / "config.json" - config_path = PATH.config / ("%s.json" % Path(__file__).stem) + config_path = PATH.config / ("%s.json" % self.__class__.__name__) super(Alert, self).__init__("休息提醒", root, ICON.alert, config_path) self.config = self.init_config() self.start_time = time() diff --git a/memorytools/plugins/copytrans/copytrans.py b/memorytools/plugins/copytrans/copytrans.py index 8b42b32..e12d05a 100644 --- a/memorytools/plugins/copytrans/copytrans.py +++ b/memorytools/plugins/copytrans/copytrans.py @@ -20,8 +20,7 @@ class CopyTrans(BasePlugin): 一个复制翻译的插件,调用谷歌翻译的接口翻译剪切板中的文本 """ def __init__(self, root) -> None: - # config_path = Path(__file__).parent / "config.json" - config_path = PATH.config / ("%s.json" % Path(__file__).stem) + config_path = PATH.config / ("%s.json" % self.__class__.__name__) super(CopyTrans, self).__init__("复制翻译", root, ICON.trans, config_path) self.config = self.init_config() self.last = '' # 记录上次的剪切板内容 diff --git a/memorytools/plugins/help/help.py b/memorytools/plugins/help/help.py index 55110df..8b0a918 100644 --- a/memorytools/plugins/help/help.py +++ b/memorytools/plugins/help/help.py @@ -14,7 +14,7 @@ class Help(BasePlugin): def __init__(self, root) -> None: - config_path = PATH.config / ("%s.json" % Path(__file__).stem) + config_path = PATH.config / ("%s.json" % self.__class__.__name__) super(Help, self).__init__("帮助", root, ICON.about, config_path) self.config = self.init_config() diff --git a/memorytools/plugins/ocr/ocr.py b/memorytools/plugins/ocr/ocr.py index d6d09be..763fc5e 100644 --- a/memorytools/plugins/ocr/ocr.py +++ b/memorytools/plugins/ocr/ocr.py @@ -18,8 +18,7 @@ class OCR(BasePlugin): def __init__(self, root): - # config_path = Path(__file__).parent / "config.json" - config_path = PATH.config / ("%s.json" % Path(__file__).stem) + config_path = PATH.config / ("%s.json" % self.__class__.__name__) super(OCR, self).__init__("OCR识别", root, ICON.ocr, config_path) self.config = self.init_config() self.text_ocr = BaiduOCR(BAIDU_ACCOUNTS) From 2e7fe89a4c13a019e71f1e7c03a8aa12eaae68f3 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Mon, 12 Oct 2020 14:52:44 +0800 Subject: [PATCH 24/28] Update traybar.py --- memorytools/tools/systray/traybar.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/memorytools/tools/systray/traybar.py b/memorytools/tools/systray/traybar.py index 8d29984..86951fd 100644 --- a/memorytools/tools/systray/traybar.py +++ b/memorytools/tools/systray/traybar.py @@ -49,6 +49,7 @@ def __init__(self, self.exit_ico = exit_ico self.refreshMenu(menu_options) + print(self._menu_options) # menu_options = menu_options or () # menu_options = menu_options + (('退出', None, SysTrayIcon.QUIT),) @@ -76,12 +77,14 @@ def __init__(self, self._register_class() def refreshMenu(self, menu_options): - '''留了一个外部刷新菜单的函数,可以动态改变菜单''' + """留了一个外部刷新菜单的函数,可以动态改变菜单""" menu_options = menu_options + (('退出', self.exit_ico, self.QUIT, False),) self._next_action_id = self.FIRST_ID self._menu_actions_by_id = set() + self._menu_actions_by_name = set() self._menu_options = self._add_ids_to_menu_options(list(menu_options)) self._menu_actions_by_id = dict(self._menu_actions_by_id) + self._menu_actions_by_name = dict(self._menu_actions_by_name) def __enter__(self): """Context manager so SysTray can automatically close""" @@ -158,6 +161,7 @@ def _add_ids_to_menu_options(self, menu_options): option_text, option_icon, option_action, option_separator = menu_option if callable(option_action) or option_action in SysTrayIcon.SPECIAL_ACTIONS: self._menu_actions_by_id.add((self._next_action_id, option_action)) + self._menu_actions_by_name.add((self._next_action_id, option_text)) result.append(menu_option + (self._next_action_id,)) elif non_string_iterable(option_action): result.append((option_text, @@ -227,6 +231,7 @@ def _destroy(self, hwnd, msg, wparam, lparam): def _notify(self, hwnd, msg, wparam, lparam): if lparam == WM_LBUTTONDBLCLK: + print(self._default_menu_index) self._execute_menu_option(self._default_menu_index + SysTrayIcon.FIRST_ID) elif lparam == WM_RBUTTONUP: self._show_menu() @@ -308,11 +313,12 @@ def _command(self, hwnd, msg, wparam, lparam): self._execute_menu_option(id) def _execute_menu_option(self, id): + option_text = self._menu_actions_by_name[id] menu_action = self._menu_actions_by_id[id] if menu_action == SysTrayIcon.QUIT: DestroyWindow(self._hwnd) else: - menu_action(self) + menu_action(option_text) def non_string_iterable(obj): try: From 53106b1af16e47ad7b2f47df6922819d59957470 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Mon, 12 Oct 2020 16:36:44 +0800 Subject: [PATCH 25/28] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=91=B8=E9=B1=BC?= =?UTF-8?q?=E6=8F=90=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- memorytools/globals.py | 3 +- memorytools/memorytools.py | 2 +- memorytools/plugins/alert/alert.py | 121 ++++++++++++++------- memorytools/plugins/base.py | 4 +- memorytools/plugins/copytrans/copytrans.py | 12 +- memorytools/plugins/ocr/ocr.py | 8 +- memorytools/tools/systray/traybar.py | 1 - 7 files changed, 95 insertions(+), 56 deletions(-) diff --git a/memorytools/globals.py b/memorytools/globals.py index 00d9891..fff162b 100644 --- a/memorytools/globals.py +++ b/memorytools/globals.py @@ -34,7 +34,8 @@ class PATH: class TEXT: hover = "Memory Tools" - alert = '你已经连续工作 %d 分钟了!是时候休息一下了!\ntip: 连续在电脑前工作太久容易脱发,得颈椎病,猝死。' + rest_alert = '你已经连续工作 %d 分钟了!是时候休息一下了!\ntip: 连续在电脑前工作太久容易脱发,得颈椎病,猝死。' + slack_alert = '你已经连续摸鱼 %d 分钟了!是时候工作一下了!\ntip: 连续摸鱼太久容易延毕,失业,流落街头。' class URL: diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index 4f0f2fb..2bd80e4 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -20,7 +20,7 @@ class MemoryTool(object): 程序的入口类 """ - version = "v2.0.0 beta" + version = "v2.1.0 beta" def __init__(self): self.plugins = [plugin(self) for plugin in plugin_list] diff --git a/memorytools/plugins/alert/alert.py b/memorytools/plugins/alert/alert.py index 0c1df73..ba3d01f 100644 --- a/memorytools/plugins/alert/alert.py +++ b/memorytools/plugins/alert/alert.py @@ -3,7 +3,7 @@ @file: alert @author: Memory @date: 2020/10/11 -@description: 用于休息提醒 +@description: 用于工作提醒 """ from time import time from .alertbox import AlertBox @@ -11,78 +11,117 @@ from tools.utils import is_check, is_pick from tools.logger import logger from plugins import BasePlugin, change_config -from pathlib import Path - - -class BaseAlert(BasePlugin): - def __init__(self): - pass +from PIL import ImageGrab class Alert(BasePlugin): def __init__(self, root) -> None: config_path = PATH.config / ("%s.json" % self.__class__.__name__) - super(Alert, self).__init__("休息提醒", root, ICON.alert, config_path) + super(Alert, self).__init__("工作提醒", root, ICON.alert, config_path) self.config = self.init_config() - self.start_time = time() + self.rest_start_time = time() + + self.slack_start_time = time() + self.last_screen = ImageGrab.grab().getdata() + self.check_interval = 10 + self.last_check_time = time() + self.similarity_thresold = 0.96 def create_menu(self): menu_options = ( - ("开启提醒", is_check(self.is_alert), self.pause_alert, True), - ('30分钟', is_pick(self.alert_time == 30), self.set_alert_time_30, False), - ('60分钟', is_pick(self.alert_time == 60), self.set_alert_time_60, False), - ('90分钟', is_pick(self.alert_time == 90), self.set_alert_time_90, False), - ('120分钟', is_pick(self.alert_time == 120), self.set_alert_time_120, False), + ("休息提醒", is_check(self.is_rest_alert), self.pause_rest_alert, True), + ('30分钟', is_pick(self.rest_time == 30), self.set_rest_time, False), + ('60分钟', is_pick(self.rest_time == 60), self.set_rest_time, False), + ('90分钟', is_pick(self.rest_time == 90), self.set_rest_time, True), + ("摸鱼提醒", is_check(self.is_slack_alert), self.pause_slack_alert, True), + ('10分钟', is_pick(self.slack_time == 10), self.set_slack_time, False), + ('15分钟', is_pick(self.slack_time == 15), self.set_slack_time, False), + ('20分钟', is_pick(self.slack_time == 20), self.set_slack_time, False), ) return menu_options def create_default_config(self) -> dict: config = { - "is_alert": True, - "alert_time": 90 + "is_rest_alert": True, + "rest_time": 60, + "is_slack_alert": True, + "slack_time": 15 } return config @change_config - def pause_alert(self, s): - self.is_alert = not self.is_alert - if self.is_alert: - self.start_time = time() + def pause_rest_alert(self, option_text): + self.is_rest_alert = not self.is_rest_alert + if self.is_rest_alert: + self.rest_start_time = time() logger.info("[休息提醒] 开启休息提醒") else: logger.info("[休息提醒] 关闭休息提醒") - # LabelBox().show("虽然你关掉了休息提醒,但还是要注意身体!", "确定") - - @change_config - def set_alert_time_30(self, s): - self.alert_time = 30 - logger.info("[休息提醒] 将休息提醒时间设置为 30 分钟.") @change_config - def set_alert_time_60(self, s): - self.alert_time = 60 - logger.info("[休息提醒] 将休息提醒时间设置为 60 分钟.") + def pause_slack_alert(self, option_text): + self.is_slack_alert = not self.is_slack_alert + if self.is_slack_alert: + self.slack_start_time = time() + logger.info("[休息提醒] 开启摸鱼提醒") + else: + logger.info("[休息提醒] 关闭摸鱼提醒") @change_config - def set_alert_time_90(self, s): - self.alert_time = 90 - logger.info("[休息提醒] 将休息提醒时间设置为 90 分钟.") + def set_rest_time(self, option_text): + self.rest_time = int(option_text[:2]) + logger.info("[休息提醒] 将休息提醒时间设置为 %d 分钟." % self.rest_time) @change_config - def set_alert_time_120(self, s): - self.alert_time = 120 - logger.info("[休息提醒] 将休息提醒时间设置为 120 分钟.") + def set_slack_time(self, option_text): + self.slack_time = int(option_text[:2]) + logger.info("[休息提醒] 将摸鱼提醒时间设置为 %d 分钟." % self.slack_time) def alert(self): - minute = (time() - self.start_time) / 60 # 分钟数 - if minute >= self.alert_time: + minute = (time() - self.rest_start_time) / 60 # 分钟数 + if minute >= self.rest_time: return True return False + def slack(self): + """ + 判断是否在摸鱼 + 首先,程序每隔 self.check_interval 秒钟检查一次屏幕,将其与上一次的屏幕进行对比, + 如果相似度超过 self.similarity_thresold, 则判断为摸鱼。 + 如果摸鱼时间超过了 self.slack_time,那么将会弹窗提醒。 + """ + check = (time() - self.last_check_time) > self.check_interval + if check: + self.last_check_time = time() + current_screen = ImageGrab.grab().getdata() + similarity = 0 + for i, j in zip(current_screen, self.last_screen): + if i == j: + similarity += 1 + similarity = similarity / len(current_screen) + # print(similarity) + self.last_screen = current_screen + + if similarity >= self.similarity_thresold: + minute = (time() - self.slack_start_time) / 60 + # print(minute, self.slack_time) + if minute >= self.slack_time: + return True + else: + self.slack_start_time = time() + + return False + def start(self): - if self.is_alert and self.alert(): - alert_message = TEXT.alert % self.alert_time - AlertBox('危险警报').show(alert_message, '等你想要继续工作了再点我') - self.start_time = time() + if self.is_rest_alert and self.alert(): + alert_message = TEXT.rest_alert % self.rest_time + AlertBox('危险警报').show(alert_message, '想要继续工作了再点我') + self.rest_start_time = time() + self.slack_start_time = time() + if self.is_slack_alert and self.slack(): + alert_message = TEXT.slack_alert % self.slack_time + AlertBox('摸鱼警报').show(alert_message, '点我开始工作') + self.rest_start_time = time() + self.slack_start_time = time() diff --git a/memorytools/plugins/base.py b/memorytools/plugins/base.py index 947978e..e2df9e7 100644 --- a/memorytools/plugins/base.py +++ b/memorytools/plugins/base.py @@ -17,8 +17,8 @@ def change_config(set_attr): :param set_attr: 更改属性的函数 :return: 装饰过的函数 """ - def wrapper(plugin, s): - f = set_attr(plugin, s) + def wrapper(plugin, option_text): + f = set_attr(plugin, option_text) plugin.save_config() plugin.root.refresh_menu() return f diff --git a/memorytools/plugins/copytrans/copytrans.py b/memorytools/plugins/copytrans/copytrans.py index e12d05a..d4565c6 100644 --- a/memorytools/plugins/copytrans/copytrans.py +++ b/memorytools/plugins/copytrans/copytrans.py @@ -54,7 +54,7 @@ def get_translator(cls): return Translator(service_urls=['translate.google.cn']) @change_config - def pause_trans(self, s): + def pause_trans(self, option_text): self.is_trans = not self.is_trans if self.is_trans: logger.info("[复制翻译] 开启复制翻译") @@ -62,24 +62,24 @@ def pause_trans(self, s): logger.info("[复制翻译] 关闭复制翻译") @change_config - def en2zh_mode(self, s): + def en2zh_mode(self, option_text): self.mode = 'en2zh' self.src, self.dest = 'en', 'zh-cn' logger.info("[复制翻译] 切换翻译模式为: 英译中") @change_config - def zh2en_mode(self, s): + def zh2en_mode(self, option_text): self.mode = 'zh2en' self.src, self.dest = 'zh-cn', 'en' logger.info("[复制翻译] 切换翻译模式为: 中译英") @change_config - def both_mode(self, s): + def both_mode(self, option_text): self.mode = 'both' logger.info("[复制翻译] 切换翻译模式为: 中英互译") @change_config - def turn_strict(self, s): + def turn_strict(self, option_text): self.strict = not self.strict if self.strict: logger.info("[复制翻译] 开启严格模式") @@ -87,7 +87,7 @@ def turn_strict(self, s): logger.info("[复制翻译] 关闭严格模式") @change_config - def turn_newline(self, s): + def turn_newline(self, option_text): self.newline = not self.newline if not self.newline: logger.info("[复制翻译] 开启去除换行") diff --git a/memorytools/plugins/ocr/ocr.py b/memorytools/plugins/ocr/ocr.py index 763fc5e..36d1582 100644 --- a/memorytools/plugins/ocr/ocr.py +++ b/memorytools/plugins/ocr/ocr.py @@ -43,7 +43,7 @@ def create_default_config(self) -> dict: return config @change_config - def pause_ocr(self, s): + def pause_ocr(self, option_text): self.is_ocr = not self.is_ocr if self.is_ocr: logger.info("[OCR识别] 开启OCR识别") @@ -51,17 +51,17 @@ def pause_ocr(self, s): logger.info("[OCR识别] 关闭OCR识别") @change_config - def text_mode(self, s): + def text_mode(self, option_text): self.mode = 'text' logger.info("[OCR识别] 切换OCR识别模式为: 文本") @change_config - def math_mode(self, s): + def math_mode(self, option_text): self.mode = 'math' logger.info("[OCR识别] 切换OCR识别模式为: 公式") @change_config - def turn_newline(self, s): + def turn_newline(self, option_text): self.newline = not self.newline if not self.newline: logger.info("[OCR识别] 开启去除换行") diff --git a/memorytools/tools/systray/traybar.py b/memorytools/tools/systray/traybar.py index 86951fd..25f3db4 100644 --- a/memorytools/tools/systray/traybar.py +++ b/memorytools/tools/systray/traybar.py @@ -49,7 +49,6 @@ def __init__(self, self.exit_ico = exit_ico self.refreshMenu(menu_options) - print(self._menu_options) # menu_options = menu_options or () # menu_options = menu_options + (('退出', None, SysTrayIcon.QUIT),) From c87479414a8648bb7040a07daaf1f18e77e6f151 Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Mon, 12 Oct 2020 17:01:05 +0800 Subject: [PATCH 26/28] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B0=8Fbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- memorytools/plugins/copytrans/transbox.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/memorytools/plugins/copytrans/transbox.py b/memorytools/plugins/copytrans/transbox.py index a03f90f..68bc55b 100644 --- a/memorytools/plugins/copytrans/transbox.py +++ b/memorytools/plugins/copytrans/transbox.py @@ -28,23 +28,23 @@ def retrans(self): sentence = self.copy_trans.remove_newline(sentence) self.set_text(self.src_text, sentence) - self.set_text(self.dest_text, "翻译中,请稍候...") + self.set_text(self.textbox, "翻译中,请稍候...") text = self.copy_trans.trans_text(sentence) - self.set_text(self.dest_text, text) + self.set_text(self.textbox, text) def show(self, src: str, dest: str): h1 = min(10, max(5, get_text_line(src) + 1)) h2 = min(10, max(5, get_text_line(dest) + 1)) self.src_text = ScrolledText(self, height=h1, background='#ffffff', font=("微软雅黑", 11)) - self.dest_text = ScrolledText(self, height=h2, background='#ffffff', font=("微软雅黑", 11)) + self.textbox = ScrolledText(self, height=h2, background='#ffffff', font=("微软雅黑", 11)) self.src_text.insert(END, str(src)) self.src_text.config() - self.dest_text.insert(END, str(dest)) + self.textbox.insert(END, str(dest)) self.src_text.pack(side='top', padx=10, pady=10) - self.dest_text.pack(side='top', padx=10, pady=10) + self.textbox.pack(side='top', padx=10, pady=10) self.start() From 6d5eed13eefeb6ffc40e64285cf4c6faaa73c49b Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Wed, 14 Oct 2020 09:46:17 +0800 Subject: [PATCH 27/28] v2.1.0 --- README.md | 44 +++++++++++++++++++----------- memorytools/__init__.py | 2 +- memorytools/memorytools.py | 2 +- memorytools/plugins/alert/alert.py | 2 +- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 3114e8f..8f9d8fe 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,12 @@ -## Memory Tools V2.0.0 Beta +## Memory Tools V2.1.0 -> 2020/10/11 更新 +> 2020/10/14 更新 --- -### 0. 前言 - -这软件到现在已经快两年了,最初只是想做一个软件帮我去除复制的PDF文本中的换行符,后面又想着直接翻译更省事。之后又觉得加个托盘图标比较酷炫,就想方设法加了一个托盘图标,但是这也使得软件只能在win下运行了。到今年疫情在家无事,又重写了整个软件,优化了外观,并且加入了OCR的接口。 - -这学期给实验室一些人用发现了挺多bug,刚好这两天因为运动损伤待在宿舍里,就重构了代码,将各个功能都封装成包,以后往里面加东西就会变得非常方便了。 - ### 1. 运行 -正如前面所说,这个软件仅支持在windows下面运行。 +该软件仅支持在windows下面运行。 - **使用exe** @@ -30,34 +24,52 @@ ### 2. 软件功能 -- **复制翻译**:翻译剪切板的文本,并弹框显示结果。 +- **复制翻译**:翻译剪切板的文本,并弹框显示结果。现在支持修改源文本并重新翻译。 - **中文-->英文**:中文翻译成英文,如果复制的文本英文的比例过高,则不会翻译。 - **英文-->中文**:英文翻译成中文,如果复制的文本中文的比例过高,则不会翻译。 - **英文 <-> 中文**:中英互译,检测复制的文本是哪种语言,然后翻译成另一种语言。 - **去除换行**:如果是从pdf上复制,则每一行末尾都会加入换行,结果就不准确,开启去除换行可以避免。 - **严格模式**:默认使用语言自动检测,如果开启严格模式,则将设置源语言。(可以在谷歌翻译上试一下,在中英文混排时可能有一点差异) - - **OCR识别**:对剪切板中的图片进行OCR识别,并弹框显示。 - **识别:文本**:识别普通的文本。 - **识别:公式**:可以识别公式,并转换成 Latex 代码。 - **去除换行**:是否去除识别后文本中的换行。识别公式时,此项不起作用。 - -- **休息提醒**:在你工作一段时间以后,提醒你该休息了。 - - **更改时间**:提醒时间默认90分钟,可以自己更改。 +- **工作提醒** + - **休息提醒:** 在你工作一段时间以后,提醒你该休息了。 + - **摸鱼提醒**: 在你摸鱼一段时间以后,提醒你该工作了。 --- ### 3. 软件说明 -1. 每次退出会保存程序的配置,下次启动时自动载入。 +1. 每次修改菜单项会保存程序的配置,下次启动时自动载入。 2. 复制翻译使用谷歌翻译的接口。 3. 如果翻译后的结果与未翻译时一样,则不会显示。 -4. OCR使用百度AI开放平台的接口,每天有一定的次数限制。 +4. OCR使用百度AI开放平台的接口,用的是我自己申请的key,每天有一定的次数限制。 5. 当OCR设置为识别公式时,仍然可以识别文本,但是可能会发生意料之外的错误。 6. 请按时休息 :smile:。 --- +### 4. 更新日志 + +- v2.1.0 [2020/10/14] + - 收到某吕姓男子的反馈,一直弹出休息提醒让摸鱼的他很难受,因此要求加入摸鱼提醒。所以我加入了简单的摸鱼检测,即隔一分钟对屏幕进行检测,和上一分钟的屏幕进行对比,如果相似度过高则标记为正在摸鱼,摸鱼时间达到预设时间则弹窗提醒。摸鱼提醒以后,休息提醒的时间将被重置。 + +- v2.0.0 [2020/10/11] + + - 重构了代码,将每个菜单项封装成一个包,搞了一套基础的运行逻辑,以后往里面加东西比较方便。 + + - 修复了关闭休息提醒软件会闪退的Bug。 + - 给复制翻译加入了重新翻译的选项,可以编辑复制的源文本并重新翻译,也可以当成一个谷歌翻译的简单GUI界面使用。 + +### 关于软件 + +这软件到现在已经快两年了,最初只是想做一个软件帮我去除复制的PDF文本中的换行符,后面又想着直接翻译更省事。之后又觉得加个托盘图标比较酷炫,就想方设法加了一个托盘图标,但是这也使得软件只能在win下运行了。到今年疫情在家无事,又重写了整个软件,优化了外观,并且加入了OCR的接口。 + +这学期给实验室一些人用发现了挺多bug,刚好这两天因为运动损伤待在宿舍里,就重构了代码,将各个功能都封装成包,以后往里面加东西就会变得非常方便了。 + + ### 关于作者 1. 作者:Memory diff --git a/memorytools/__init__.py b/memorytools/__init__.py index 6a6a2cb..dd8aab0 100644 --- a/memorytools/__init__.py +++ b/memorytools/__init__.py @@ -6,6 +6,6 @@ __title__ = 'memorytools' -__version__ = '2.0.0' +__version__ = '2.1.0' __author__ = 'Memory' __copyright__ = 'Copyright 2020 Memory' diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index 2bd80e4..7e83a8b 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -20,7 +20,7 @@ class MemoryTool(object): 程序的入口类 """ - version = "v2.1.0 beta" + version = "v2.1.0" def __init__(self): self.plugins = [plugin(self) for plugin in plugin_list] diff --git a/memorytools/plugins/alert/alert.py b/memorytools/plugins/alert/alert.py index ba3d01f..6571816 100644 --- a/memorytools/plugins/alert/alert.py +++ b/memorytools/plugins/alert/alert.py @@ -23,7 +23,7 @@ def __init__(self, root) -> None: self.slack_start_time = time() self.last_screen = ImageGrab.grab().getdata() - self.check_interval = 10 + self.check_interval = 60 self.last_check_time = time() self.similarity_thresold = 0.96 From 6a95f44fd824db9a508f0206945db32f5f712a5f Mon Sep 17 00:00:00 2001 From: MemoryD <732527427@qq.com> Date: Thu, 24 Dec 2020 13:07:17 +0800 Subject: [PATCH 28/28] v2.2.0 --- README.md | 5 +++-- memorytools/__init__.py | 4 ++-- memorytools/memorytools.py | 4 ++-- memorytools/plugins/copytrans/copytrans.py | 10 +++++----- memorytools/plugins/help/help.py | 2 ++ 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 8f9d8fe..19b8f03 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## Memory Tools V2.1.0 -> 2020/10/14 更新 +> 2020/12/24 更新 --- @@ -52,7 +52,8 @@ --- ### 4. 更新日志 - +- v2.2.0 [2020/12/24] + - 修复了翻译接口出错的问题。 - v2.1.0 [2020/10/14] - 收到某吕姓男子的反馈,一直弹出休息提醒让摸鱼的他很难受,因此要求加入摸鱼提醒。所以我加入了简单的摸鱼检测,即隔一分钟对屏幕进行检测,和上一分钟的屏幕进行对比,如果相似度过高则标记为正在摸鱼,摸鱼时间达到预设时间则弹窗提醒。摸鱼提醒以后,休息提醒的时间将被重置。 diff --git a/memorytools/__init__.py b/memorytools/__init__.py index dd8aab0..c34d732 100644 --- a/memorytools/__init__.py +++ b/memorytools/__init__.py @@ -1,11 +1,11 @@ """ @name: __init__ @author: Memory -@date: 2020/10/11 +@date: 2020/12/24 """ __title__ = 'memorytools' -__version__ = '2.1.0' +__version__ = '2.2.0' __author__ = 'Memory' __copyright__ = 'Copyright 2020 Memory' diff --git a/memorytools/memorytools.py b/memorytools/memorytools.py index 7e83a8b..3e15480 100644 --- a/memorytools/memorytools.py +++ b/memorytools/memorytools.py @@ -2,7 +2,7 @@ """ @name: memorytools @author: Memory -@date: 2020/10/11 +@date: 2020/12/24 @description: 项目的入口文件 """ from time import sleep @@ -20,7 +20,7 @@ class MemoryTool(object): 程序的入口类 """ - version = "v2.1.0" + version = "v2.2.0" def __init__(self): self.plugins = [plugin(self) for plugin in plugin_list] diff --git a/memorytools/plugins/copytrans/copytrans.py b/memorytools/plugins/copytrans/copytrans.py index d4565c6..5205e6a 100644 --- a/memorytools/plugins/copytrans/copytrans.py +++ b/memorytools/plugins/copytrans/copytrans.py @@ -2,12 +2,12 @@ """ @file: copytrans @author: Memory -@date: 2020/10/11 +@date: 2020/12/24 @description: 复制翻译插件的定义 """ from pathlib import Path from .transbox import TransBox -from googletransx import Translator +from google_trans_new import google_translator from tools.utils import is_check, is_pick, judge_language, paste_clip, copy_clip from tools.logger import logger from requests.exceptions import ConnectionError @@ -51,7 +51,7 @@ def create_default_config(self) -> dict: @classmethod def get_translator(cls): - return Translator(service_urls=['translate.google.cn']) + return google_translator() @change_config def pause_trans(self, option_text): @@ -150,9 +150,9 @@ def trans_text(self, sentence: str): for i in range(3): try: if self.strict: - text = self.translator.translate(sentence, src=self.src, dest=self.dest).text + text = self.translator.translate(sentence, lang_src=self.src, lang_tgt=self.dest) else: - text = self.translator.translate(sentence, dest=self.dest).text + text = self.translator.translate(sentence, lang_tgt=self.dest) return text except ConnectionError as ce: logger.error("[复制翻译] 连接失败: %s" % ce) diff --git a/memorytools/plugins/help/help.py b/memorytools/plugins/help/help.py index 8b0a918..c2d3d87 100644 --- a/memorytools/plugins/help/help.py +++ b/memorytools/plugins/help/help.py @@ -11,6 +11,8 @@ from globals import ICON, PATH, URL from plugins import BasePlugin +# + class Help(BasePlugin): def __init__(self, root) -> None: