From 5c85041135020001c2163f129e6940da2bb31639 Mon Sep 17 00:00:00 2001 From: renyu <1154817144@qq.com> Date: Fri, 25 Nov 2022 15:42:37 +0800 Subject: [PATCH 01/70] =?UTF-8?q?Bug=20512=20-=20=E6=96=87=E7=AB=A0?= =?UTF-8?q?=E6=9C=97=E8=AF=BB=E9=97=AE=E9=A2=98=20=E5=9C=A8fillwowrd.js?= =?UTF-8?q?=E4=B8=AD=E6=B7=BB=E5=8A=A0=E4=BA=86stopRead()=E5=87=BD?= =?UTF-8?q?=E6=95=B0=EF=BC=8C=E5=B0=86=E5=85=B6=E6=B7=BB=E5=8A=A0=E7=BB=99?= =?UTF-8?q?=E5=AF=B9=E5=BA=94=E6=8C=89=E9=92=AE=E6=88=96=E8=B6=85=E9=93=BE?= =?UTF-8?q?=E6=8E=A5=E4=BB=A5=E7=BB=88=E6=AD=A2=E6=9C=97=E8=AF=BB=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/static/js/fillword.js | 4 ++++ app/templates/userpage_get.html | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/static/js/fillword.js b/app/static/js/fillword.js index 505808e..ba249dd 100644 --- a/app/static/js/fillword.js +++ b/app/static/js/fillword.js @@ -62,3 +62,7 @@ function onReadClick() { function onChooseClick() { isChoose = !isChoose; } + +function stopRead() { + reader.cancel(); +} \ No newline at end of file diff --git a/app/templates/userpage_get.html b/app/templates/userpage_get.html index 9e3891b..24bff60 100644 --- a/app/templates/userpage_get.html +++ b/app/templates/userpage_get.html @@ -23,15 +23,15 @@

English Pal for {{ username }} - 退出 - 重设密码 + 退出 + 重设密码

{{ flashed_messages|safe }} - 下一篇 Next Article + 下一篇 Next Article {% if session.get('articleID') != session.get('old_articleID') %} {% if session.get('old_articleID') != None %} - 上一篇 Previous Article + 上一篇 Previous Article {% endif%} {% endif %} @@ -52,7 +52,7 @@

收集生词吧 (可以在正文中划词,也可以复制黏贴)


- +
{% if session.get['thisWord'] %} From 3609421976313c1dd9e9551d65a11f445d32c632 Mon Sep 17 00:00:00 2001 From: Rui <603992850@qq.com> Date: Tue, 29 Nov 2022 16:53:59 +0800 Subject: [PATCH 02/70] =?UTF-8?q?=E5=AF=B9=E7=A1=AE=E8=AE=A4=E5=AF=86?= =?UTF-8?q?=E7=A0=81=E9=83=A8=E5=88=86=E4=BF=9D=E8=AF=81=E6=9C=89=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E8=AF=BB=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/templates/signup.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/signup.html b/app/templates/signup.html index bbc653a..55881ff 100644 --- a/app/templates/signup.html +++ b/app/templates/signup.html @@ -126,7 +126,7 @@ h1{

-

+

From 7e3004a2e68d1affff03daa45fb344bde91b19c2 Mon Sep 17 00:00:00 2001 From: Rui <603992850@qq.com> Date: Tue, 29 Nov 2022 16:55:48 +0800 Subject: [PATCH 03/70] =?UTF-8?q?=E6=92=A4=E5=9B=9E=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/templates/signup.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/signup.html b/app/templates/signup.html index 55881ff..64eb28d 100644 --- a/app/templates/signup.html +++ b/app/templates/signup.html @@ -126,7 +126,7 @@ h1{

-

+

From b65ffa6054a416122340148d96e4e07353989ca8 Mon Sep 17 00:00:00 2001 From: LiangLiGang <3103167775@qq.com> Date: Thu, 1 Dec 2022 21:04:12 +0800 Subject: [PATCH 04/70] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8D=95=E8=AF=8D?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=8B=BE=E9=80=89,=E5=B9=B6=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/templates/userpage_post.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/templates/userpage_post.html b/app/templates/userpage_post.html index 725ee09..1163787 100644 --- a/app/templates/userpage_post.html +++ b/app/templates/userpage_post.html @@ -20,7 +20,7 @@ EnglishPal Study Room for {{username}} -

勾选不认识的单词

+

取消勾选认识的单词

{% for x in lst %} @@ -30,7 +30,7 @@ : {{word}} ({{x[1]}}) - +

{% endfor %} From 89c12337d54147a3874255def57e8dbe3ff14ba8 Mon Sep 17 00:00:00 2001 From: Rui <603992850@qq.com> Date: Fri, 2 Dec 2022 15:48:45 +0800 Subject: [PATCH 05/70] =?UTF-8?q?=E5=9C=A8README=E4=B8=AD=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index ec92598..fb70948 100644 --- a/README.md +++ b/README.md @@ -181,4 +181,14 @@ Demo video link: https://b23.tv/QuB77m Bug report: http://118.25.96.118/bugzilla/show_bug.cgi?id=215 + +### 丁锐 + +修复了以下漏洞 + +漏洞:新用户在创建账号时,不需要输入确定密码也可以注册成功,并且新账户可以正常使用。 + +Bug report:http://118.25.96.118/bugzilla/show_bug.cgi?id=489 + + *Last modified on 2021-10-17* \ No newline at end of file From d58dacd71cc4a0a693b9d8a123f5ea24375dd8c1 Mon Sep 17 00:00:00 2001 From: ShumTin <970206989@qq.com> Date: Tue, 6 Dec 2022 14:40:50 +0800 Subject: [PATCH 06/70] =?UTF-8?q?=E4=BF=AE=E5=A4=8DBug508,=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E5=B8=A6=E6=9C=89=E7=89=B9=E6=AE=8A=E5=AD=97=E7=AC=A6?= =?UTF-8?q?|=E7=9A=84=E5=8D=95=E8=AF=8D=E5=9C=A8=E6=96=87=E7=AB=A0?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E9=AB=98=E4=BA=AE=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/static/js/highlight.js | 2 ++ app/wordfreqCMD.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/static/js/highlight.js b/app/static/js/highlight.js index 1003918..7b3cab2 100644 --- a/app/static/js/highlight.js +++ b/app/static/js/highlight.js @@ -29,6 +29,8 @@ function highLight() { const list = allWords.split(" "); for (let i = 0; i < list.length; ++i) { list[i] = list[i].replace(/(^\s*)|(\s*$)/g, ""); //消除单词两边的空字符 + list[i] = list[i].replace('|', ""); + list[i] = list[i].replace('?', ""); if (list[i] !== "" && "".indexOf(list[i]) === -1 && "".indexOf(list[i]) === -1) { //将文章中所有出现该单词word的地方改为:" " + word + " "。 正则表达式RegExp()中,"\\s"代表单词前后必须要有空格,以防止只对单词中的部分字符高亮的情况出现。 articleContent = articleContent.replace(new RegExp("\\s"+list[i]+"\\s", "g"), " " + list[i] + " "); diff --git a/app/wordfreqCMD.py b/app/wordfreqCMD.py index 9ee7e56..7c3f186 100644 --- a/app/wordfreqCMD.py +++ b/app/wordfreqCMD.py @@ -39,7 +39,7 @@ def file2str(fname):#文件转字符 def remove_punctuation(s): # 这里是s是形参 (parameter)。函数被调用时才给s赋值。 - special_characters = '_©~=+[]*&$%^@.,?!:;#()"“”—‘’' # 把里面的字符都去掉 + special_characters = '\_©~<=>+-/[]*&$%^@.,?!:;#()"“”—‘’{}' # 把里面的字符都去掉 for c in special_characters: s = s.replace(c, ' ') # 防止出现把 apple,apple 移掉逗号后变成 appleapple 情况 s = s.replace('--', ' ') From 6327b117110e2c41e7888d16c1e8fa46298124ff Mon Sep 17 00:00:00 2001 From: MR LAN <1348141770@qq.com> Date: Tue, 6 Dec 2022 16:06:13 +0800 Subject: [PATCH 07/70] Made folder 'frequency' under folder 'static', and added a README file under folder 'frequency' --- app/static/frequency/README.txt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 app/static/frequency/README.txt diff --git a/app/static/frequency/README.txt b/app/static/frequency/README.txt new file mode 100644 index 0000000..3a9c1f9 --- /dev/null +++ b/app/static/frequency/README.txt @@ -0,0 +1,5 @@ +This folder holds users' vocabulary files. +Each file ends with .pickle. +For example, mrlan.pickle is the vocabulary file for user mrlan. + + From f37ea182f64e0484541b0a27fb317acb97e4ea07 Mon Sep 17 00:00:00 2001 From: ShumTin <970206989@qq.com> Date: Tue, 6 Dec 2022 17:02:59 +0800 Subject: [PATCH 08/70] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E7=94=9F=E8=AF=8D?= =?UTF-8?q?=E5=BA=93=E8=BF=87=E6=BB=A4|?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/wordfreqCMD.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/wordfreqCMD.py b/app/wordfreqCMD.py index 7c3f186..c4f8a63 100644 --- a/app/wordfreqCMD.py +++ b/app/wordfreqCMD.py @@ -39,7 +39,7 @@ def file2str(fname):#文件转字符 def remove_punctuation(s): # 这里是s是形参 (parameter)。函数被调用时才给s赋值。 - special_characters = '\_©~<=>+-/[]*&$%^@.,?!:;#()"“”—‘’{}' # 把里面的字符都去掉 + special_characters = '\_©~<=>+-/[]*&$%^@.,?!:;#()"“”—‘’{}|' # 把里面的字符都去掉 for c in special_characters: s = s.replace(c, ' ') # 防止出现把 apple,apple 移掉逗号后变成 appleapple 情况 s = s.replace('--', ' ') From c76d4f21ecc26f81cd23e9a95e2ff45c9106ac3b Mon Sep 17 00:00:00 2001 From: xujiahui <1419417159@qq.com> Date: Tue, 13 Dec 2022 15:40:17 +0800 Subject: [PATCH 09/70] SPM2022F-CONTRIBUTORS-XieQiuHan --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ec92598..71f82e4 100644 --- a/README.md +++ b/README.md @@ -180,5 +180,6 @@ Demo video link: https://b23.tv/QuB77m Bug report: http://118.25.96.118/bugzilla/show_bug.cgi?id=215 +小组:谢秋涵 -*Last modified on 2021-10-17* \ No newline at end of file +*Last modified on 2021-10-17* From 086dfcb6eb3cb8aae63e93b21ca071381bb24b41 Mon Sep 17 00:00:00 2001 From: np1717 <1004186200@qq.com> Date: Mon, 19 Dec 2022 17:54:10 +0800 Subject: [PATCH 10/70] fix bug 489 --- .DS_Store | Bin 0 -> 6148 bytes app/templates/signup.html | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..7b9e3399d7747d6de8838936b3d6673c4464d460 GIT binary patch literal 6148 zcmeHK%Wl&^6g|@f>NG;i0;Fy#Sz=p-RE1Wk8#km2kl54+7Jx!r8*0_@gxDdKqDWc8 zKky4|`4awx6`Xlgic`8_flxG8nmKo7?wRX3)_6PsM0XPJ0WAO?i^BRAt3Q|;SLK>* z*d8?~)Ex3G%4Ecrn$DS1z$x&*E1>pn4FilYdYV=C?=eT(zqIK^*r;e)jO;G|9*wfJ zC_9}WVxv~Sb$ip>^qSt=@LW#Aa!^i+?qK{{wO&Y>MOXeHdYLBEe(UZNnU{k!PsW;% z#tB2-yh`&}PP=lF$A#vGX25HBjecu;HrspD+4c7yAIx|C+2JAmhx-TfdBeMR|H08| z{~{aa^0N_L@SCLVj>RkZLdUM=Q#j5unSWr9iuMp;f)p8Iv{B%EMU!ugS=M9=JxHA4 z0tv==ubD}eBX(9eO*~_CPEN|YxPhgfaXC{1r#Qhe^F1fFF+{wQ=jRHe#V1PeQLjgN zL!Gr`#x_b^qO9^cH}G}oeY5Fotrf8Q!)vbfD&69o0#1RyQ9ykkd=`a)#f3rr>0qU= z0K_`Gwb9o<|3qJP5Ce+~gY2ORLnRujuvZLW?+(JyIUd;fg+W7y(3v@p%`EHvBoKj-xvs)*8l(j literal 0 HcmV?d00001 diff --git a/app/templates/signup.html b/app/templates/signup.html index 64eb28d..e070d8f 100644 --- a/app/templates/signup.html +++ b/app/templates/signup.html @@ -125,8 +125,8 @@ h1{

-

-

+

+

From 74eccfbebd04899a08ff5d3ab56d41c0e83808bf Mon Sep 17 00:00:00 2001 From: xujiahui <1419417159@qq.com> Date: Tue, 20 Dec 2022 19:55:02 +0800 Subject: [PATCH 11/70] =?UTF-8?q?=E9=87=8D=E5=A4=8D=E6=96=87=E7=AB=A0?= =?UTF-8?q?=E5=88=B7=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 -- app/templates/userpage_get.html | 16 +++++++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 71f82e4..bdf08ef 100644 --- a/README.md +++ b/README.md @@ -180,6 +180,4 @@ Demo video link: https://b23.tv/QuB77m Bug report: http://118.25.96.118/bugzilla/show_bug.cgi?id=215 -小组:谢秋涵 - *Last modified on 2021-10-17* diff --git a/app/templates/userpage_get.html b/app/templates/userpage_get.html index 9e3891b..7d8f981 100644 --- a/app/templates/userpage_get.html +++ b/app/templates/userpage_get.html @@ -17,10 +17,19 @@ {% endfor %} {% endif %} + EnglishPal Study Room for {{ username }} - +

English Pal for {{ username }} 退出 @@ -29,6 +38,11 @@ {{ flashed_messages|safe }} 下一篇 Next Article + {% if session.get('articleID') == session.get('old_articleID') %} + {% if session.get('old_articleID') != None %} + 出bug了 + {% endif%} + {% endif %} {% if session.get('articleID') != session.get('old_articleID') %} {% if session.get('old_articleID') != None %} 上一篇 Previous Article From 0209548896d0dbbcfae95b0836306f5c1e0ed2f6 Mon Sep 17 00:00:00 2001 From: yugaoxiang Date: Sat, 31 Dec 2022 18:25:13 +0800 Subject: [PATCH 12/70] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/main.py | 74 ++++++++++++++++++++- app/templates/admin_index.html | 112 ++++++++++++++++++++++++++++++++ app/templates/mainpage_get.html | 4 +- app/templates/userpage_get.html | 1 + 4 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 app/templates/admin_index.html diff --git a/app/main.py b/app/main.py index e311bb0..bcbd3f8 100644 --- a/app/main.py +++ b/app/main.py @@ -5,7 +5,7 @@ # Copyright 2019 (C) Hui Lan # Written permission must be obtained from the author for commercial uses. ########################################################################### - +from datetime import datetime from flask import escape from Login import * from Article import * @@ -102,6 +102,78 @@ def mainpage(): d_len=d_len, lst=lst, yml=Yaml.yml) +def insert_article(content, source='manual_input', level=5, question=''): + sql = f"INSERT into article (text,source, date, level, question) VALUES " \ + f"('{content}','{source}','{datetime.now().strftime('%Y-%m-%d')}', '{level}', '{question}');" + print(sql) + rq = RecordQuery('./static/wordfreqapp.db') + rq.instructions(sql) + rq.do() + + +def get_articles(): + sql = f"SELECT * from article order by -article_id;" + rq = RecordQuery('./static/wordfreqapp.db') + rq.instructions(sql) + rq.do() + result = rq.get_results() + return result + + +def get_users(): + sql = f"SELECT * from user;" + rq = RecordQuery('./static/wordfreqapp.db') + rq.instructions(sql) + rq.do() + result = rq.get_results() + return result + + +def update_user_password(username, password='123456'): + password = md5(username + password) + sql = f"UPDATE user SET password='{password}' where name='{username}';" + rq = RecordQuery('./static/wordfreqapp.db') + rq.instructions(sql) + rq.do() + + +@app.route("/admin", methods=['GET', 'POST']) +def admin(): + ''' + ''' + # 未登录,跳转到未登录界面 + if not session.get('logged_in'): + return render_template('not_login.html') + + # 获取session里的用户名 + username = session.get('username') + + context = { + # 'user': request.user, + 'text_list': get_articles(), + 'user_list': get_users(), + 'username': username + } + if request.method == 'GET': + return render_template('admin_index.html', **context) + else: + data = request.form + content = data.get('content') + source = data.get('source', '') + question = data.get('question', '') + username = data.get('username') + if content: + insert_article( + content=content, + source=source, + question=question + ) + context['text_list'] = get_articles() + if username: + update_user_password(username) + return render_template('admin_index.html', **context) + + if __name__ == '__main__': ''' diff --git a/app/templates/admin_index.html b/app/templates/admin_index.html new file mode 100644 index 0000000..be88556 --- /dev/null +++ b/app/templates/admin_index.html @@ -0,0 +1,112 @@ + + + + + + + + +

+ +
+
重置选中用户密码
+
+
+ + +
+ + +
+
+ +
+ {% if tips %} + + {% endif %} + +
+
录入文章
+
+
+ + + + + + + + +
+ + +
+
+
+ +
+
文章列表
+
+ {% for text in text_list %} +
+
+
{{ text['source'] }}
+ Date:{{ text['date'] }} Level:{{ text['level'] }} +
+

{{ text['text'] }}

+
+ {% endfor %} + +
+
+ + + + + + + + diff --git a/app/templates/mainpage_get.html b/app/templates/mainpage_get.html index cbb51a6..4cc4417 100644 --- a/app/templates/mainpage_get.html +++ b/app/templates/mainpage_get.html @@ -23,9 +23,9 @@

English Pal - Learn English smartly!

{% if session['logged_in'] %} - {{session['username']}}

+ {{session['username']}} 管理

{% else %} -

登录 注册 使用说明

+

管理 登录 注册 使用说明

{{random_ads|safe}}

{% endif %} diff --git a/app/templates/userpage_get.html b/app/templates/userpage_get.html index 24bff60..863d2e4 100644 --- a/app/templates/userpage_get.html +++ b/app/templates/userpage_get.html @@ -23,6 +23,7 @@

English Pal for {{ username }} + 管理 退出 重设密码

From 43bd0bd09d3c345e52262ad2a3bfb58e83a39858 Mon Sep 17 00:00:00 2001 From: yugaoxiang Date: Sun, 1 Jan 2023 22:05:32 +0800 Subject: [PATCH 13/70] update requirement.txt --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 2746a3b..8552794 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -Flask==1.1.2 +Flask==2.1.0 selenium==3.141.0 PyYAML~=6.0 From 03353d49b151ea730c1396077c10dde48cc81a32 Mon Sep 17 00:00:00 2001 From: mrlan Date: Sun, 29 Jan 2023 10:57:58 +0800 Subject: [PATCH 14/70] Bug525-Hui (#79) Co-authored-by: Hui Lan Reviewed-on: http://121.4.94.30:3000/mrlan/EnglishPal/pulls/79 Co-authored-by: mrlan Co-committed-by: mrlan --- app/Login.py | 4 ++-- app/templates/expiry.html | 2 +- app/user_service.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Login.py b/app/Login.py index 1ada0af..8e0030b 100644 --- a/app/Login.py +++ b/app/Login.py @@ -1,6 +1,6 @@ import hashlib import string -from datetime import datetime +from datetime import datetime, timedelta from UseSqlite import InsertQuery, RecordQuery path_prefix = '/var/www/wordfreq/wordfreq/' @@ -23,7 +23,7 @@ def verify_user(username, password): def add_user(username, password): start_date = datetime.now().strftime('%Y%m%d') - expiry_date = '20221230' + expiry_date = (datetime.now() + timedelta(days=30)).strftime('%Y%m%d') # will expire after 30 days # 将用户名和密码一起加密,以免暴露不同用户的相同密码 password = md5(username + password) rq = InsertQuery(path_prefix + 'static/wordfreqapp.db') diff --git a/app/templates/expiry.html b/app/templates/expiry.html index 797a109..9464325 100644 --- a/app/templates/expiry.html +++ b/app/templates/expiry.html @@ -5,7 +5,7 @@ 账号过期 -

您的账号{{ username }}过期。

+

您的账号过期(过期日 {{expiry_date}})。

为了提高服务质量,English Pal 收取会员费用, 每天1元。

请决定你要试用的时间长度,扫描下面支付宝二维码支付。 支付时请注明English Pal Membership Fee。 我们会于12小时内激活账号。

支付宝二维码

diff --git a/app/user_service.py b/app/user_service.py index 79c7888..2d10404 100644 --- a/app/user_service.py +++ b/app/user_service.py @@ -107,7 +107,7 @@ def userpage(username): # 用户过期 user_expiry_date = session.get('expiry_date') if datetime.now().strftime('%Y%m%d') > user_expiry_date: - return render_template('expiry.html') + return render_template('expiry.html', expiry_date=user_expiry_date) # 获取session里的用户名 username = session.get('username') From 972a1a5524dde8fcdea9ad3b63f7e397ebba504a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E7=A7=8B=E4=BC=9F?= <2658626578@qq.com> Date: Sun, 29 Jan 2023 11:49:27 +0800 Subject: [PATCH 15/70] Bug490-ChenQiuwei (#63) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复Bug-490,使注册时确认密码能够发挥作用,在确认密码与所设置密码不一致时,能够提示“确认密码与输入密码不一致”。 Co-authored-by: 2658626578 <2658626578@qq.com> Co-authored-by: Hui Lan Reviewed-on: http://121.4.94.30:3000/mrlan/EnglishPal/pulls/63 Co-authored-by: 陈秋伟 <2658626578@qq.com> Co-committed-by: 陈秋伟 <2658626578@qq.com> --- app/account_service.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/account_service.py b/app/account_service.py index dc854a3..9b1c46b 100644 --- a/app/account_service.py +++ b/app/account_service.py @@ -5,7 +5,6 @@ from Login import check_username_availability, verify_user, add_user, get_expiry # 初始化蓝图 accountService = Blueprint("accountService", __name__) - ### Sign-up, login, logout ### @accountService.route("/signup", methods=['GET', 'POST']) def signup(): @@ -20,6 +19,7 @@ def signup(): # POST方法需判断是否注册成功,再根据结果返回不同的内容 username = escape(request.form['username']) password = escape(request.form['password']) + password2 = escape(request.form['password2']) #! 添加如下代码为了过滤注册时的非法字符 warn = WarningMessage(username) @@ -32,6 +32,8 @@ def signup(): return render_template('signup.html') elif len(password.strip()) < 4: # 密码过短 return '密码过于简单。' + elif password != password2: + return '确认密码与输入密码不一致!' else: # 添加账户信息 add_user(username, password) verified = verify_user(username, password) @@ -48,6 +50,7 @@ def signup(): return '用户名密码验证失败。' + @accountService.route("/login", methods=['GET', 'POST']) def login(): ''' From 9cdc9c6f7fe06fcdb485c9ca038f953a67cf30e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=9B=A8=E5=B3=B0?= <1141730046@qq.com> Date: Sun, 29 Jan 2023 12:01:19 +0800 Subject: [PATCH 16/70] Bug521-LiYuFeng-Refactor (#72) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @mrlan 蓝老师: 本次改进内容如下: 1. 对生词居中问题进行修改,现在已经不会居中了。 2. 对于单词数量基数大而导致的排序速度慢的问题,我们进行了优化,提升了排序的速度。 3. 对用户交互进行了优化,当用户点击“熟悉”或“不熟悉”之后,会自动进行排序,并会跳转到那个单词的位置,用抖动的效果来提示用户。 Co-authored-by: isaac <1141730046@qq.com> Reviewed-on: http://121.4.94.30:3000/mrlan/EnglishPal/pulls/72 Co-authored-by: 李雨峰 <1141730046@qq.com> Co-committed-by: 李雨峰 <1141730046@qq.com> --- app/static/js/word_operation.js | 139 ++++++++++++++++++++++++++++++-- app/templates/userpage_get.html | 64 ++++++++++----- 2 files changed, 177 insertions(+), 26 deletions(-) diff --git a/app/static/js/word_operation.js b/app/static/js/word_operation.js index a55fb6e..a9af300 100644 --- a/app/static/js/word_operation.js +++ b/app/static/js/word_operation.js @@ -7,10 +7,20 @@ function familiar(theWord) { url:"/" + username + "/" + word + "/familiar", success:function(response){ let new_freq = freq - 1; - if(new_freq <1) { - $("#p_" + theWord).remove(); + const allow_move = document.getElementById("move_dynamiclly").checked; + if (allow_move) { + + if (new_freq <= 0) { + removeWord(theWord); + } else { + renderWord({ word: theWord, freq: new_freq }); + } } else { - $("#freq_" + theWord).text(new_freq); + if(new_freq <1) { + $("#p_" + theWord).remove(); + } else { + $("#freq_" + theWord).text(new_freq); + } } } }); @@ -25,7 +35,12 @@ function unfamiliar(theWord) { url:"/" + username + "/" + word + "/unfamiliar", success:function(response){ let new_freq = parseInt(freq) + 1; - $("#freq_" + theWord).text(new_freq); + const allow_move = document.getElementById("move_dynamiclly").checked; + if (allow_move) { + renderWord({ word: theWord, freq: new_freq }); + } else { + $("#freq_" + theWord).text(new_freq); + } } }); } @@ -37,7 +52,121 @@ function delete_word(theWord) { type:"GET", url:"/" + username + "/" + word + "/del", success:function(response){ - $("#p_" + theWord).remove(); + const allow_move = document.getElementById("move_dynamiclly").checked; + if (allow_move) { + removeWord(theWord); + } else { + $("#p_" + theWord).remove(); + } } }); } + +/* + * interface Word { + * word: string, + * freq: number + * } +* */ + +/** + * 传入一个词频HTML元素,将其解析为Word类型的对象 + */ +function parseWord(element) { + const word = element + .querySelector("a.btn.btn-light[role=button]") // 获取当前词频元素的词汇元素 + .innerText // 获取词汇值; + const freq = Number.parseInt(element.querySelector(`#freq_${word}`).innerText); // 获取词汇的数量 + return { + word, + freq + }; +} + +/** + * 使用模板将传入的单词转换为相应的HTML字符串 +*/ +function wordTemplate(word) { + // 这个模板应当与 templates/userpage_get.html 中的

...

保持一致 + return `

+ ${word.word} + ( ${word.freq} ) + 熟悉 + 不熟悉 + 删除 +

`; +} + +/** + * 删除某一词频元素 + * 此处word为词频元素对应的单词 + */ +function removeWord(word) { + // 根据词频信息删除元素 + const element_to_remove = document.getElementById(`p_${word}`); + if (element_to_remove != null) { + element_to_remove.remove(); + } +} + +function renderWord(word) { + const container = document.querySelector(".word-container"); + // 删除原有元素 + removeWord(word.word); + // 插入新元素 + let inserted = false; + const new_element = elementFromString(wordTemplate(word)); + for (const current of container.children) { + const cur_word = parseWord(current); + // 找到第一个词频比它小的元素,插入到这个元素前面 + if (compareWord(cur_word, word) == -1) { + container.insertBefore(new_element, current); + inserted = true; + break; + } + } + // 当word就是词频最小的词时,把他补回去 + if (!inserted) { + container.appendChild(new_element); + } + // 让发生变化的元素抖动 + new_element.classList.add("shaking"); + // 移动到该元素 + new_element.scrollIntoView({behavior: "smooth", block: "center", inline: "nearest"}); + // 抖动完毕后删除抖动类 + setTimeout(() => { + new_element.classList.remove("shaking"); + }, 1600); +} + +/** + * 从string中创建一个HTML元素并返回 + */ +function elementFromString(string) { + const d = document.createElement('div'); + d.innerHTML = string; + return d.children.item(0); +} + +/** + * 对比两个单词: + * 当first小于second时返回-1 + * 当first等于second时返回0 + * 当first大于second时返回1 + */ +function compareWord(first, second) { + if (first.freq < second.freq) { + return -1; + } + if (first.freq > second.freq) { + return 1; + } + if (first.word < second.word) { + return -1; + } + if (first.word > second.word) { + return 1; + } + return 0; +} \ No newline at end of file diff --git a/app/templates/userpage_get.html b/app/templates/userpage_get.html index 24bff60..dc0d497 100644 --- a/app/templates/userpage_get.html +++ b/app/templates/userpage_get.html @@ -19,19 +19,33 @@ {% endif %} EnglishPal Study Room for {{ username }} + +

English Pal for {{ username }} - 退出 - 重设密码 + 退出 + 重设密码

{{ flashed_messages|safe }} - 下一篇 Next Article + 下一篇 Next Article {% if session.get('articleID') != session.get('old_articleID') %} {% if session.get('old_articleID') != None %} - 上一篇 Previous Article + 上一篇 Previous Article {% endif%} {% endif %} @@ -52,7 +66,7 @@

收集生词吧 (可以在正文中划词,也可以复制黏贴)


- +
{% if session.get['thisWord'] %} @@ -67,22 +81,30 @@ {% endif %} {% if d_len > 0 %} -

我的生词簿

- {% for x in lst3 %} - {% set word = x[0] %} - {% set freq = x[1] %} - {% if session.get('thisWord') == x[0] and session.get('time') == 1 %} - - {% endif %} -

- {{ word }} - ( {{ freq }} ) - 熟悉 - 不熟悉 - 删除 -

- {% endfor %} +

+ 我的生词簿 + +

+ +
+ {% for x in lst3 %} + {% set word = x[0] %} + {% set freq = x[1] %} + {% if session.get('thisWord') == x[0] and session.get('time') == 1 %} + {% endif %} +

+ {{ word }} + ( {{ freq }} ) + 熟悉 + 不熟悉 + 删除 +

+ {% endfor %} +
{% endif %}
From e10dbf9d67114e36e77bb773b631435844b3655c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BF=97=E8=B1=AA?= <1594799762@qq.com> Date: Sun, 29 Jan 2023 12:48:52 +0800 Subject: [PATCH 17/70] Bug507-WuWenZhuo (#70) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### 修复了生词簿为空时,双击文章单词无法高亮的问题 通过增加一个判断,判断生词簿为空时,不把生词簿的内容进行处理,仅处理选中单词。 ### 修复了生词簿为空时,取消高亮后,导致文章格式混乱的问题 原代码中,从数据库提取文章放到网页上时,使用的是.innerText的方法,导致原文章里包含的
标签丢失,导致文章格式混乱的问题。 Co-authored-by: unknown Co-authored-by: Hui Lan Reviewed-on: http://121.4.94.30:3000/mrlan/EnglishPal/pulls/70 Co-authored-by: 王志豪 <1594799762@qq.com> Co-committed-by: 王志豪 <1594799762@qq.com> --- README.md | 3 +++ app/static/js/highlight.js | 22 ++++++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index fb70948..c12fc0b 100644 --- a/README.md +++ b/README.md @@ -191,4 +191,7 @@ Bug report: http://118.25.96.118/bugzilla/show_bug.cgi?id=215 Bug report:http://118.25.96.118/bugzilla/show_bug.cgi?id=489 +======= +实验3,添加我的组名:WuWenZhuo + *Last modified on 2021-10-17* \ No newline at end of file diff --git a/app/static/js/highlight.js b/app/static/js/highlight.js index 7b3cab2..5ec9663 100644 --- a/app/static/js/highlight.js +++ b/app/static/js/highlight.js @@ -22,11 +22,17 @@ function getWord() { function highLight() { if (!isHighlight) return; - let articleContent = document.getElementById("article").innerText; + let articleContent = document.getElementById("article").innerText; //将原来的.innerText改为.innerHtml,使用innerText会把原文章中所包含的
标签去除,导致处理后的文章内容失去了原来的格式 let pickedWords = document.getElementById("selected-words"); // words picked to the text area let dictionaryWords = document.getElementById("selected-words2"); // words appearing in the user's new words list - let allWords = pickedWords.value + " " + dictionaryWords.value; - const list = allWords.split(" "); + let allWords = ""; //初始化allWords的值,避免进入判断后编译器认为allWords未初始化的问题 + if(dictionaryWords != null){//增加一个判断,检查生词本里面是否为空,如果为空,allWords只添加选中的单词 + allWords = pickedWords.value + " " + dictionaryWords.value; + } + else{ + allWords = pickedWords.value + " "; + } + const list = allWords.split(" ");//将所有的生词放入一个list中,用于后续处理 for (let i = 0; i < list.length; ++i) { list[i] = list[i].replace(/(^\s*)|(\s*$)/g, ""); //消除单词两边的空字符 list[i] = list[i].replace('|', ""); @@ -40,15 +46,15 @@ function highLight() { } function cancelHighlighting() { - let articleContent = document.getElementById("article").innerText; + let articleContent = document.getElementById("article").innerText;//将原来的.innerText改为.innerHtml,原因同上 let pickedWords = document.getElementById("selected-words"); const dictionaryWords = document.getElementById("selected-words2"); const list = pickedWords.value.split(" "); if (pickedWords != null) { for (let i = 0; i < list.length; ++i) { list[i] = list[i].replace(/(^\s*)|(\s*$)/g, ""); - if (list[i] !== "") { - articleContent = articleContent.replace("" + list[i] + "", "list[i]"); + if (list[i] !== "") { //原来判断的代码中,替换的内容为“list[i]”这个字符串,这明显是错误的,我们需要替换的是list[i]里的内容 + articleContent = articleContent.replace(new RegExp(""+list[i]+"", "g"), list[i]); } } } @@ -57,8 +63,8 @@ function cancelHighlighting() { for (let i = 0; i < list2.length; ++i) { list2 = dictionaryWords.value.split(" "); list2[i] = list2[i].replace(/(^\s*)|(\s*$)/g, ""); - if (list2[i] !== "") { - articleContent = articleContent.replace("" + list[i] + "", "list[i]"); + if (list2[i] !== "") { //原来代码中,替换的内容为“list[i]”这个字符串,这明显是错误的,我们需要替换的是list[i]里的内容 + articleContent = articleContent.replace(new RegExp(""+list2[i]+"", "g"), list2[i]); } } } From 92a8b4a9944b9509e52cd09a7eb35aa4ccb052b4 Mon Sep 17 00:00:00 2001 From: mrlan Date: Mon, 30 Jan 2023 15:44:01 +0800 Subject: [PATCH 18/70] Lanhui-update-README2 (#80) Co-authored-by: Lan Hui <1348141770@qq.com> Reviewed-on: http://121.4.94.30:3000/mrlan/EnglishPal/pulls/80 Co-authored-by: mrlan Co-committed-by: mrlan --- .DS_Store | Bin 6148 -> 0 bytes README.md | 65 ++++++++++++++++++++++++++---------------------------- 2 files changed, 31 insertions(+), 34 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 7b9e3399d7747d6de8838936b3d6673c4464d460..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%Wl&^6g|@f>NG;i0;Fy#Sz=p-RE1Wk8#km2kl54+7Jx!r8*0_@gxDdKqDWc8 zKky4|`4awx6`Xlgic`8_flxG8nmKo7?wRX3)_6PsM0XPJ0WAO?i^BRAt3Q|;SLK>* z*d8?~)Ex3G%4Ecrn$DS1z$x&*E1>pn4FilYdYV=C?=eT(zqIK^*r;e)jO;G|9*wfJ zC_9}WVxv~Sb$ip>^qSt=@LW#Aa!^i+?qK{{wO&Y>MOXeHdYLBEe(UZNnU{k!PsW;% z#tB2-yh`&}PP=lF$A#vGX25HBjecu;HrspD+4c7yAIx|C+2JAmhx-TfdBeMR|H08| z{~{aa^0N_L@SCLVj>RkZLdUM=Q#j5unSWr9iuMp;f)p8Iv{B%EMU!ugS=M9=JxHA4 z0tv==ubD}eBX(9eO*~_CPEN|YxPhgfaXC{1r#Qhe^F1fFF+{wQ=jRHe#V1PeQLjgN zL!Gr`#x_b^qO9^cH}G}oeY5Fotrf8Q!)vbfD&69o0#1RyQ9ykkd=`a)#f3rr>0qU= z0K_`Gwb9o<|3qJP5Ce+~gY2ORLnRujuvZLW?+(JyIUd;fg+W7y(3v@p%`EHvBoKj-xvs)*8l(j diff --git a/README.md b/README.md index c12fc0b..29e74dd 100644 --- a/README.md +++ b/README.md @@ -11,15 +11,14 @@ Hui Lan EnglishPal allows the user to build his list of new English words -picked from articles selected for him according his vocabulary level. +picked from articles selected for him to read according his vocabulary level. EnglishPal will determine a user's vocabulary level based on his picked words. After that, it will recommend articles for him to read, in order to booster his English vocabulary furthermore. -## Run it on a local machine - +## Run on your own laptop `python3 main.py` -Make sure you have the SQLite database file in `app/static` (see below). +Make sure you have put the SQLite database file in the path `app/static` (see below). ## Run it as a Docker container @@ -29,32 +28,32 @@ Assuming that docker has been installed and that you are a sudo user (i.e., sudo `sudo ./build.sh` -Open your favourite Internet browser and enter this URL address: `http://ip-address:90`. +Open your favourite Internet browser and enter this URL address: `http://ip-address:90`. Note: you must update the variable `DEPLOYMENT_DIR` in `build.sh`. ### Explanation on the commands in build.sh -My steps for deploying English on the server. +My steps for deploying English on a Ubuntu server. - ssh to ubuntu@118.*.*.118 -- cd to /home/lanhui/englishpal2/EnglishPal +- cd to `/home/lanhui/englishpal2/EnglishPal` - Stop all docker service: `sudo service docker restart`. If you know the docker container ID, then the above command is an overkill. Use the following command instead: `sudo docker stop ContainerID`. You could get all container IDs with the following command: `sudo docker ps` -- Rebuild container. Run the following command to rebuild a docker image after the code gets updated: `sudo docker build -t englishpal .` +- Rebuild container. Run the following command to rebuild a docker image each time after the source code gets updated: `sudo docker build -t englishpal .` -- Run the application: `sudo docker run -d -p 90:80 -v /home/lanhui/englishpal2/EnglishPal/app/static/frequency:/app/static/frequency -t englishpal`. If you use `sudo docker run -d -p 90:80 -t englishpal`, data will be lost after terminating the program. +- Run the application: `sudo docker run -d -p 90:80 -v /home/lanhui/englishpal2/EnglishPal/app/static/frequency:/app/static/frequency -t englishpal`. If you use `sudo docker run -d -p 90:80 -t englishpal`, data will be lost after terminating the program. If you want to automatically restart the docker image after each system reboot, add the option `--restart=always` after `docker run`. -- Save space: `sudo docker system prune -a -f` +- Save disk space: `sudo docker system prune -a -f` + +`build.sh` contains all the above commands. Run "sudo ./build.sh" to rebuild and start the web application. -### Other useful docker commands +#### Other useful docker commands - `sudo docker ps -a` -- `sudo docker logs image_name`, where image_name could be obtained from `sudo docker ps`. - -`build.sh` contains all the above commands. Run "sudo ./build.sh" to rebuild and run the web application. +- `sudo docker logs image_name`, where `image_name` could be obtained from `sudo docker ps`. @@ -68,6 +67,10 @@ All articles are stored in the `article` table in a SQLite file called To add articles, open and edit `app/static/wordfreqapp.db` using DB Browser for SQLite (https://sqlitebrowser.org). +### Extending an account's expiry date + +By default, an account's expiry is 30 days after first sign-up. To extend account's expiry date, open and edit `user` table in `app/static/wordfreqapp.db`. Simply update field `expiry_date`. + ### Exporting the database Export wordfreqapp.db to wordfreqapp.sql using the following commands: @@ -92,33 +95,31 @@ sqlite3 wordfreqapp.db`. Delete wordfreqapp.db first if it exists. ### Uploading wordfreqapp.db to the server -`pscp wordfreqapp.db lanhui@118.*.*.118:/home/lanhui/englishpal/app/static` +`pscp wordfreqapp.db lanhui@118.*.*.118:/home/lanhui/englishpal2/EnglishPal/app/static` ## Feedback -We welcome feedback on EnglishPal. +We welcome feedback on EnglishPal. Feedback examples: -### Respondent 1 +### Feedback 1 + +- "Need a phone app. I use phone a lot. You cannot ask students to use computers." -"Need a phone app. I use phone a lot. You cannot ask students to use computers." - -Can take a picture for text. Automatic translation. - -### Respondent 2 +### Feedback 2 -“成为会员”改成“注册” +- “成为会员”改成“注册” -“登出”改成“退出” +- “登出”改成“退出” -“收集生词吧”改成“生词收集栏” +- “收集生词吧”改成“生词收集栏” -“不要自动显示下一篇” +- 不要自动显示下一篇 -需要有“上一篇”、“下一篇” +- 需要有“上一篇”、“下一篇”按钮。 @@ -137,7 +138,7 @@ EnglishPal's bugs and improvement suggestions are recorded in [Bugzilla](http:// - Usability testing -## Improvements made by contributors +## Improvements made by contributors (incomplete list) ### 朱文绮 @@ -159,7 +160,6 @@ too many words that they already know, on the other hand, it can reduce unnecessary memory occupied by the database, in addition, it can also improve the simplicity of the page. -More information at: http://118.25.96.118/kanboard/?controller=TaskViewController&action=readonly&task_id=736&token=81a561da57ff7a172da17a480f0d421ff3bc69efbd29437daef90b1b8959 ### 占健豪 @@ -188,10 +188,7 @@ Bug report: http://118.25.96.118/bugzilla/show_bug.cgi?id=215 漏洞:新用户在创建账号时,不需要输入确定密码也可以注册成功,并且新账户可以正常使用。 -Bug report:http://118.25.96.118/bugzilla/show_bug.cgi?id=489 +Bug report: http://118.25.96.118/bugzilla/show_bug.cgi?id=489 -======= -实验3,添加我的组名:WuWenZhuo - -*Last modified on 2021-10-17* \ No newline at end of file +*Last modified on 2023-01-30* \ No newline at end of file From a1955341c6c2495dd7c8f73727d341b780c38a6c Mon Sep 17 00:00:00 2001 From: Hui Lan Date: Tue, 31 Jan 2023 16:39:11 +0800 Subject: [PATCH 19/70] =?UTF-8?q?Fix=20bug=20501=20-=20=E7=89=B9=E6=AE=8A?= =?UTF-8?q?=E5=AD=97=E7=AC=A6&=E5=8A=A0=E5=85=A5=E7=94=9F=E8=AF=8D?= =?UTF-8?q?=E5=BA=93=E5=90=8E=E5=88=A0=E9=99=A4=E6=8C=89=E9=92=AE=E5=A4=B1?= =?UTF-8?q?=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/static/js/word_operation.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/static/js/word_operation.js b/app/static/js/word_operation.js index a9af300..ea6a6e8 100644 --- a/app/static/js/word_operation.js +++ b/app/static/js/word_operation.js @@ -47,7 +47,7 @@ function unfamiliar(theWord) { function delete_word(theWord) { let username = $("#username").text(); - let word = $("#word_" + theWord).text(); + let word = theWord.replace('&', '&'); $.ajax({ type:"GET", url:"/" + username + "/" + word + "/del", @@ -104,6 +104,7 @@ function wordTemplate(word) { */ function removeWord(word) { // 根据词频信息删除元素 + word = word.replace('&', '&'); const element_to_remove = document.getElementById(`p_${word}`); if (element_to_remove != null) { element_to_remove.remove(); @@ -169,4 +170,4 @@ function compareWord(first, second) { return 1; } return 0; -} \ No newline at end of file +} From 93390374ad3e67568c3a2ce5376f683734516a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E9=97=AE=E4=B8=89=E4=B8=8D=E7=9F=A5?= <178428409@qq.com> Date: Tue, 21 Feb 2023 20:05:48 +0800 Subject: [PATCH 20/70] =?UTF-8?q?=E6=A0=87=E6=B3=A8=E4=B9=8B=E5=89=8D?= =?UTF-8?q?=E9=98=9F=E4=BC=8D=E7=9A=84=E6=94=B9=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/templates/userpage_get.html | 42 +++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/app/templates/userpage_get.html b/app/templates/userpage_get.html index 7d8f981..ee9a7f0 100644 --- a/app/templates/userpage_get.html +++ b/app/templates/userpage_get.html @@ -17,18 +17,21 @@ {% endfor %} {% endif %} - +{# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #} EnglishPal Study Room for {{ username }} +{# original code: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #}

English Pal for {{ username }} @@ -37,17 +40,19 @@

{{ flashed_messages|safe }} - 下一篇 Next Article + 下一篇 Next Article +{# add code !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #} {% if session.get('articleID') == session.get('old_articleID') %} {% if session.get('old_articleID') != None %} 出bug了 - {% endif%} + {% endif %} {% endif %} {% if session.get('articleID') != session.get('old_articleID') %} {% if session.get('old_articleID') != None %} 上一篇 Previous Article - {% endif%} + {% endif %} {% endif %} +{# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #}

阅读文章并回答问题

{{ today_article|safe }}
@@ -60,9 +65,9 @@
- +
-
+

收集生词吧 (可以在正文中划词,也可以复制黏贴)


@@ -88,8 +93,9 @@ {% if session.get('thisWord') == x[0] and session.get('time') == 1 %} {% endif %} -

- + {{ word }} ( {{ freq }} ) 熟悉 @@ -109,9 +115,9 @@ From 944c931c9b65d6f566a365d78f4bc3f214861c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E9=97=AE=E4=B8=89=E4=B8=8D=E7=9F=A5?= <178428409@qq.com> Date: Wed, 8 Mar 2023 16:33:13 +0800 Subject: [PATCH 21/70] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=BA=86=E5=AF=B9bug50?= =?UTF-8?q?9=E7=9A=84=E4=BF=AE=E5=A4=8D=EF=BC=8C=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E9=A1=B9=E7=9B=AE=EF=BC=88=E5=8E=BB=E6=8E=89?= =?UTF-8?q?=E4=BA=86=E4=B8=9A=E5=8A=A1=E4=B8=AD=E7=9A=84=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Article.py | 73 +++++++++++++++------------------ app/account_service.py | 57 +++++-------------------- app/main.py | 3 +- app/templates/login.html | 37 +++++++++++++---- app/templates/mainpage_get.html | 2 +- app/templates/reset.html | 45 ++++++++++++++++---- app/templates/signup.html | 51 ++++++++++++++++++++--- app/templates/userpage_get.html | 59 ++++++++++++++------------ app/user_service.py | 28 +++++-------- 9 files changed, 199 insertions(+), 156 deletions(-) diff --git a/app/Article.py b/app/Article.py index 04a32ea..707ad91 100644 --- a/app/Article.py +++ b/app/Article.py @@ -32,12 +32,14 @@ def get_article_body(s): return '\n'.join(lst) -def get_today_article(user_word_list, articleID): +def get_today_article(user_word_list, existing_articles): rq = RecordQuery(path_prefix + 'static/wordfreqapp.db') - if articleID == None: + if existing_articles is None: + existing_articles = [0, []] # existing_articles[0]:为existing_articles[1]的索引;existing_articles[1]:之前显示文章的id列表,越后越新 + if existing_articles[0] > len(existing_articles[1])-1: rq.instructions("SELECT * FROM article") else: - rq.instructions('SELECT * FROM article WHERE article_id=%d' % (articleID)) + rq.instructions('SELECT * FROM article WHERE article_id=%d' % (existing_articles[1][existing_articles[0]])) rq.do() result = rq.get_results() random.shuffle(result) @@ -50,33 +52,39 @@ def get_today_article(user_word_list, articleID): d = {} d_user = load_freq_history(user_word_list) user_level = user_difficulty_level(d_user, d3) # more consideration as user's behaviour is dynamic. Time factor should be considered. - random.shuffle(result) # shuffle list - d = random.choice(result) - text_level = text_difficulty_level(d['text'], d3) - if articleID == None: + text_level = 0 + flag = False + if existing_articles[0] > len(existing_articles[1])-1: # 下一篇 for reading in result: text_level = text_difficulty_level(reading['text'], d3) factor = random.gauss(0.8, 0.1) # a number drawn from Gaussian distribution with a mean of 0.8 and a stand deviation of 1 - if within_range(text_level, user_level, (8.0 - user_level) * factor): + if within_range(reading['article_id'] not in existing_articles[1] and text_level, user_level, (8.0 - user_level) * factor): # 新的文章之前没有出现过且符合一定范围的水平 d = reading + existing_articles[1].append(d['article_id']) # 列表添加新的文章id;下面进行 + flag = True break + else: # 上一篇 + d = random.choice(result) + text_level = text_difficulty_level(d['text'], d3) + flag = True - s = '

' % ( - user_level, text_level) - s += '

Article added on: %s

' % (d['date']) - s += '
' - article_title = get_article_title(d['text']) - article_body = get_article_body(d['text']) - s += '

%s

' % (article_title) - s += '

%s

' % (article_body) - s += '

%s

' % (d['source']) - s += '

%s

' % (get_question_part(d['question'])) - s = s.replace('\n', '
') - s += '%s' % (get_answer_part(d['question'])) - s += '
' - session['articleID'] = d['article_id'] - return s + today_article = None + if flag: + today_article = { + "user_level": '%4.2f' % user_level, + "text_level": '%4.2f' % text_level, + "date": d['date'], + "article_title": get_article_title(d['text']), + "article_body": get_article_body(d['text']), + "source": d["source"], + "question": get_question_part(d['question']), + "answer": get_answer_part(d['question']) + } + else: + existing_articles[0] -= 1 + + return existing_articles, today_article def load_freq_history(path): @@ -116,21 +124,4 @@ def get_answer_part(s): flag = 1 elif flag == 1: result.append(line) - # https://css-tricks.com/snippets/javascript/showhide-element/ - js = ''' - - ''' - html_code = js - html_code += '\n' - html_code += '\n' - html_code += '\n' % ('\n'.join(result)) - return html_code \ No newline at end of file + return '\n'.join(result) \ No newline at end of file diff --git a/app/account_service.py b/app/account_service.py index 9b1c46b..c1bd64c 100644 --- a/app/account_service.py +++ b/app/account_service.py @@ -19,21 +19,15 @@ def signup(): # POST方法需判断是否注册成功,再根据结果返回不同的内容 username = escape(request.form['username']) password = escape(request.form['password']) - password2 = escape(request.form['password2']) #! 添加如下代码为了过滤注册时的非法字符 warn = WarningMessage(username) if str(warn) != 'OK': - return str(warn) + return jsonify({'status': '3', 'warn': str(warn)}) available = check_username_availability(username) if not available: # 用户名不可用 - flash('用户名 %s 已经被注册。' % (username)) - return render_template('signup.html') - elif len(password.strip()) < 4: # 密码过短 - return '密码过于简单。' - elif password != password2: - return '确认密码与输入密码不一致!' + return jsonify({'status': '0'}) else: # 添加账户信息 add_user(username, password) verified = verify_user(username, password) @@ -43,11 +37,10 @@ def signup(): session[username] = username session['username'] = username session['expiry_date'] = get_expiry_date(username) - session['articleID'] = None - return '

恭喜,你已成功注册, 你的用户名是 %s

\ -

开始使用 返回首页

' % (username, username, username) + session['existing_articles'] = None + return jsonify({'status': '2'}) else: - return '用户名密码验证失败。' + return jsonify({'status': '1'}) @@ -59,13 +52,7 @@ def login(): ''' if request.method == 'GET': # GET请求 - if not session.get('logged_in'): - # 未登录,返回登录页面 - return render_template('login.html') - else: - # 已登录,提示信息并显示登出按钮 - return '你已登录 %s。 登出点击这里。' % ( - session['username'], session['username']) + return render_template('login.html') elif request.method == 'POST': # POST方法用于判断登录是否成功 # check database and verify user @@ -79,10 +66,10 @@ def login(): session['username'] = username user_expiry_date = get_expiry_date(username) session['expiry_date'] = user_expiry_date - session['articleID'] = None - return redirect(url_for('user_bp.userpage', username=username)) + session['existing_articles'] = None + return jsonify({'status': '1'}) else: - return '无法通过验证。' + return jsonify({'status': '0'}) @accountService.route("/logout", methods=['GET', 'POST']) @@ -115,31 +102,9 @@ def reset(): # POST请求用于提交修改后信息 old_password = escape(request.form['old-password']) new_password = escape(request.form['new-password']) - - re_new_password = escape(request.form['re-new-password']) # 确认新密码 - if re_new_password != new_password: #验证新密码两次输入是否相同 - return '新密码不匹配,请重新输入' - if len(new_password) < 4: #验证新密码长度,原则参照注册模块 - return '密码过于简单。(密码长度至少4位)' - flag = change_password(username, old_password, new_password) # flag表示是否修改成功 if flag: session['logged_in'] = False - return \ -''' - - -''' - + return jsonify({'status':'1'}) # 修改成功 else: - return \ -''' - - -''' + return jsonify({'status':'2'}) # 修改失败 diff --git a/app/main.py b/app/main.py index e311bb0..59e0b88 100644 --- a/app/main.py +++ b/app/main.py @@ -39,8 +39,7 @@ def get_random_ads(): 返回随机广告 :return: 一个广告(包含HTML标签) ''' - ads = random.choice(['个性化分析精准提升', '你的专有单词本', '智能捕捉阅读弱点,针对性提高你的阅读水平']) - return ads + '。 试试吧!' + return random.choice(['个性化分析精准提升', '你的专有单词本', '智能捕捉阅读弱点,针对性提高你的阅读水平']) def appears_in_test(word, d): diff --git a/app/templates/login.html b/app/templates/login.html index a347e22..ccf6f34 100644 --- a/app/templates/login.html +++ b/app/templates/login.html @@ -1,28 +1,47 @@ {% block body %} {% if session['logged_in'] %} -You're logged in already! +你已登录 {{ session['username'] }}。 登出点击这里。 {% else %} - + +

- - - - - + + + +
- - {% endif %} {% endblock %} diff --git a/app/templates/mainpage_get.html b/app/templates/mainpage_get.html index cbb51a6..7f02c12 100644 --- a/app/templates/mainpage_get.html +++ b/app/templates/mainpage_get.html @@ -26,7 +26,7 @@ {{session['username']}}

{% else %}

登录 注册 使用说明

-

{{random_ads|safe}}

+

{{ random_ads }}。 试试吧!

{% endif %}

粘贴1篇文章 (English only)

diff --git a/app/templates/reset.html b/app/templates/reset.html index 902d046..d29855b 100644 --- a/app/templates/reset.html +++ b/app/templates/reset.html @@ -2,6 +2,38 @@ + +
@@ -9,14 +41,11 @@

Reset Password

-
- - - - - -
+ + + + +
{% endblock %} \ No newline at end of file diff --git a/app/templates/signup.html b/app/templates/signup.html index 1fd05f0..c70e4ba 100644 --- a/app/templates/signup.html +++ b/app/templates/signup.html @@ -6,6 +6,47 @@ You're logged in already! Logout. {% else %} + +

{{ get_flashed_messages()[0] | safe }}

@@ -15,12 +56,10 @@ You're logged in already! Logout.

Sign Up

-
-

-

-

- -
+

+

+

+
diff --git a/app/templates/userpage_get.html b/app/templates/userpage_get.html index ea91c58..5ef86c7 100644 --- a/app/templates/userpage_get.html +++ b/app/templates/userpage_get.html @@ -18,17 +18,6 @@ {% endfor %} {% endif %} -{# // add !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #} - -{# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #} EnglishPal Study Room for {{ username }} -{# original code: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #} - +

English Pal for {{ username }} 退出 重设密码

- {{ flashed_messages|safe }} + {% for message in messages %} + + {% endfor %} 下一篇 Next Article -{# add code !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #} - {% if session.get('articleID') == session.get('old_articleID') %} - {% if session.get('old_articleID') != None %} - 出bug了 - {% endif %} + {% if session.get('existing_articles')[0] != None and session.get('existing_articles')[0] !=0 %} + 上一篇 Previous Article {% endif %} - {% if session.get('articleID') != session.get('old_articleID') %} - {% if session.get('old_articleID') != None %} - 上一篇 Previous Article - {% endif %} - {% endif %} -{# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #}

阅读文章并回答问题

-
{{ today_article|safe }}
+
+ {% if today_article %} + +

Article added on: {{ today_article["date"] }}


+

+

{{ today_article["article_title"] }}


+

{{ today_article["article_body"] }}


+

{{ today_article['source'] }}


+

{{ today_article['question'] }}


+ + +
+
+ {% else %} + + {% endif %} +
生词高亮 大声朗读 diff --git a/app/user_service.py b/app/user_service.py index 2d10404..2c91391 100644 --- a/app/user_service.py +++ b/app/user_service.py @@ -29,9 +29,10 @@ def user_reset(username): :param username: 用户名 :return: 返回页面内容 ''' - session['old_articleID'] = session.get('articleID') if request.method == 'GET': - session['articleID'] = None + existing_articles = session.get("existing_articles") + existing_articles[0] += 1 + session["existing_articles"] = existing_articles return redirect(url_for('user_bp.userpage', username=username)) else: return 'Under construction' @@ -44,7 +45,9 @@ def user_back(username): :return: 返回页面内容 ''' if request.method == 'GET': - session['articleID'] = session.get('old_articleID') + existing_articles = session.get("existing_articles") + existing_articles[0] -= 1 + session["existing_articles"] = existing_articles return redirect(url_for('user_bp.userpage', username=username)) @@ -130,11 +133,14 @@ def userpage(username): words = '' for x in lst3: words += x[0] + ' ' + existing_articles, today_article = get_today_article(user_freq_record, session.get('existing_articles')) + session['existing_articles'] = existing_articles + # 通过 today_article,加载前端的显示页面 return render_template('userpage_get.html', username=username, session=session, - flashed_messages=get_flashed_messages_if_any(), - today_article=get_today_article(user_freq_record, session['articleID']), + flashed_messages=get_flashed_messages(), + today_article=today_article, d_len=len(d), lst3=lst3, yml=Yaml.yml, @@ -173,15 +179,3 @@ def get_time(): ''' return datetime.now().strftime('%Y%m%d%H%M') # upper to minutes -def get_flashed_messages_if_any(): - ''' - 在用户界面显示黄色提示信息 - :return: 包含HTML标签的提示信息 - ''' - messages = get_flashed_messages() - s = '' - for message in messages: - s += '' - return s From 376ef9bcbcd32298895e6875bbc307c84e962a2e Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Mon, 20 Mar 2023 20:08:14 +0800 Subject: [PATCH 22/70] feat: add pong orm requirement --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 8552794..1972e7d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ Flask==2.1.0 selenium==3.141.0 PyYAML~=6.0 +pony==0.7.16 From df82748518afdabf323696ad7dfce0ff6265e0ca Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Mon, 20 Mar 2023 20:09:32 +0800 Subject: [PATCH 23/70] feat: create classes necessary for orm operations --- app/model.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 app/model.py diff --git a/app/model.py b/app/model.py new file mode 100644 index 0000000..a913e65 --- /dev/null +++ b/app/model.py @@ -0,0 +1,30 @@ +from pony.orm import * + +db = Database() +db.bind("sqlite", "./static/wordfreqapp.db", create_db=True) # bind sqlit file + + +class User(db.Entity): + _table_ = "user" # table name + name = PrimaryKey(str) + password = Optional(str) + start_date = Optional(str) + expiry_date = Optional(str) + + +class Article(db.Entity): + _table_ = "article" # table name + article_id = PrimaryKey(int, auto=True) + text = Optional(str) + source = Optional(str) + date = Optional(str) + level = Optional(str) + question = Optional(str) + + +db.generate_mapping(create_tables=True) # must mapping after class declaration + + +if __name__ == "__main__": + with db_session: + print(Article[2].text) # test get article which id=2 text content From e2b165ada84b7ed4827e2f211f4aa55d9218a009 Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Mon, 20 Mar 2023 20:11:37 +0800 Subject: [PATCH 24/70] fix: add url 'admin' into banned url list --- app/Login.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Login.py b/app/Login.py index 8e0030b..f914359 100644 --- a/app/Login.py +++ b/app/Login.py @@ -98,7 +98,7 @@ class UserName: for c in self.username: # a user name must not include special characters, except non-leading periods or underscores if c in string.punctuation and c is not '.' and c is not '_': return f'{c} is not allowed in the user name.' - if self.username in ['signup', 'login', 'logout', 'reset', 'mark', 'back', 'unfamiliar', 'familiar', 'del']: + if self.username in ['signup', 'login', 'logout', 'reset', 'mark', 'back', 'unfamiliar', 'familiar', 'del', "admin"]: return 'You used a restricted word as your user name. Please come up with a better one.' return 'OK' From 13d8977636f9fe41b67a06d403ce03cecd630165 Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Mon, 20 Mar 2023 20:15:58 +0800 Subject: [PATCH 25/70] fix: set specific management displays for admin --- app/templates/userpage_get.html | 7 ++----- app/user_service.py | 3 ++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/templates/userpage_get.html b/app/templates/userpage_get.html index fbe281d..efb55da 100644 --- a/app/templates/userpage_get.html +++ b/app/templates/userpage_get.html @@ -37,14 +37,11 @@

English Pal for {{ username }} -<<<<<<< HEAD + {% if username == admin_name%} 管理 + {% endif %} 退出 重设密码 -======= - 退出 - 重设密码 ->>>>>>> master

{{ flashed_messages|safe }} diff --git a/app/user_service.py b/app/user_service.py index 2d10404..215f0e5 100644 --- a/app/user_service.py +++ b/app/user_service.py @@ -1,5 +1,5 @@ from datetime import datetime - +from admin_service import ADMIN_NAME from flask import * # from app import Yaml @@ -131,6 +131,7 @@ def userpage(username): for x in lst3: words += x[0] + ' ' return render_template('userpage_get.html', + admin_name=ADMIN_NAME, username=username, session=session, flashed_messages=get_flashed_messages_if_any(), From ade10e58431e141ef576fc77d37286ddc73988a9 Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Mon, 20 Mar 2023 20:16:48 +0800 Subject: [PATCH 26/70] feat: add admin_service blueprint --- app/admin_service.py | 118 +++++++++++++++++++++ app/main.py | 77 +------------- app/templates/admin_index.html | 184 +++++++++++++++++---------------- 3 files changed, 216 insertions(+), 163 deletions(-) create mode 100644 app/admin_service.py diff --git a/app/admin_service.py b/app/admin_service.py new file mode 100644 index 0000000..87d2610 --- /dev/null +++ b/app/admin_service.py @@ -0,0 +1,118 @@ +from flask import * +from model import * +from pony.orm import * +from Yaml import yml +from Login import md5 +from datetime import datetime + +# ? from difficulty import text_difficulty_level + +ADMIN_NAME = "114514" # unique admin name +_cur_page = 1 # current article page +_page_size = 5 # article sizes per page +adminService = Blueprint("admin_service", __name__) + + +@adminService.route("/admin", methods=["GET", "POST"]) +def admin(): + global _cur_page, _page_size + # 未登录,跳转到未登录界面 + if not session.get("logged_in"): + return render_template("not_login.html") + + # 获取session里的用户名 + username = session.get("username") + if username != ADMIN_NAME: + return "You are not admin!" + + article_len = get_articles_len() + try: + _page_size = min(int(request.args.get("size", 5)), article_len) + if _page_size <= 0: + raise ZeroDivisionError + _cur_page = min(int(request.args.get("page", 1)), article_len // _page_size) + except ValueError: + return "page parmas must be int!" + except ZeroDivisionError: + return "page size must bigger than zero" + + context = { + "text_len": article_len, + "page_size": _page_size, + "cur_page": _cur_page, + "text_list": get_page_articles(_cur_page, _page_size), + "user_list": get_users(), + "username": username, + "yml": yml, + } + + def _update_context(): + article_len = get_articles_len() + context["text_len"] = article_len + context["text_list"] = get_page_articles(_cur_page, _page_size) + + if request.method == "GET": + if delete_id := int(request.args.get("delete_id", 0)): # delete article + delete_article(delete_id) + _update_context() + else: + data = request.form + content = data.get("content", "") + source = data.get("source", "") + question = data.get("question", "") + username = data.get("username", "") + if content: + add_article(content, source, question) + _update_context() + if username: + update_user_password(username) + + return render_template("admin_index.html", **context) + + +def add_article(content, source="manual_input", question="No question"): + with db_session: + # add one atricle to sqlite + Article( + text=content, + source=source, + date=datetime.now().strftime("%-d %b %Y"), # format style of `5 Oct 2022` + level="1", + question=question, + ) + # ? There is a question that: + # ? How can i get one article level? + # ? I try to use the function `text_difficulty_level(content,{"test":1})` + # ? However, i lose one dict parma from pickle + # ? So I temporarily fixed the level to 1 + + +def delete_article(article_id): + article_id &= 0xFFFFFFFF # max 32 bits + with db_session: + if article := Article.select(article_id=article_id): + article.first().delete() + + +def get_articles_len(): + with db_session: + return len(Article.select()[:]) + + +def get_page_articles(num, size): + with db_session: + return [ + x + for x in Article.select().order_by(desc(Article.article_id)).page(num, size) + ] + + +def get_users(): + with db_session: + return User.select()[:] + + +def update_user_password(username, password="123456"): + with db_session: + if user := User.select(name=username).first(): + user.password = md5(username + password) diff --git a/app/main.py b/app/main.py index bcbd3f8..2af57e3 100644 --- a/app/main.py +++ b/app/main.py @@ -5,24 +5,24 @@ # Copyright 2019 (C) Hui Lan # Written permission must be obtained from the author for commercial uses. ########################################################################### -from datetime import datetime from flask import escape from Login import * from Article import * import Yaml from user_service import userService from account_service import accountService +from admin_service import adminService app = Flask(__name__) app.secret_key = 'lunch.time!' # 将蓝图注册到Lab app app.register_blueprint(userService) app.register_blueprint(accountService) +app.register_blueprint(adminService) path_prefix = '/var/www/wordfreq/wordfreq/' path_prefix = './' # comment this line in deployment - def get_random_image(path): ''' 返回随机图 @@ -102,79 +102,6 @@ def mainpage(): d_len=d_len, lst=lst, yml=Yaml.yml) -def insert_article(content, source='manual_input', level=5, question=''): - sql = f"INSERT into article (text,source, date, level, question) VALUES " \ - f"('{content}','{source}','{datetime.now().strftime('%Y-%m-%d')}', '{level}', '{question}');" - print(sql) - rq = RecordQuery('./static/wordfreqapp.db') - rq.instructions(sql) - rq.do() - - -def get_articles(): - sql = f"SELECT * from article order by -article_id;" - rq = RecordQuery('./static/wordfreqapp.db') - rq.instructions(sql) - rq.do() - result = rq.get_results() - return result - - -def get_users(): - sql = f"SELECT * from user;" - rq = RecordQuery('./static/wordfreqapp.db') - rq.instructions(sql) - rq.do() - result = rq.get_results() - return result - - -def update_user_password(username, password='123456'): - password = md5(username + password) - sql = f"UPDATE user SET password='{password}' where name='{username}';" - rq = RecordQuery('./static/wordfreqapp.db') - rq.instructions(sql) - rq.do() - - -@app.route("/admin", methods=['GET', 'POST']) -def admin(): - ''' - ''' - # 未登录,跳转到未登录界面 - if not session.get('logged_in'): - return render_template('not_login.html') - - # 获取session里的用户名 - username = session.get('username') - - context = { - # 'user': request.user, - 'text_list': get_articles(), - 'user_list': get_users(), - 'username': username - } - if request.method == 'GET': - return render_template('admin_index.html', **context) - else: - data = request.form - content = data.get('content') - source = data.get('source', '') - question = data.get('question', '') - username = data.get('username') - if content: - insert_article( - content=content, - source=source, - question=question - ) - context['text_list'] = get_articles() - if username: - update_user_password(username) - return render_template('admin_index.html', **context) - - - if __name__ == '__main__': ''' 运行程序 diff --git a/app/templates/admin_index.html b/app/templates/admin_index.html index be88556..03d6ee4 100644 --- a/app/templates/admin_index.html +++ b/app/templates/admin_index.html @@ -1,112 +1,120 @@ - + + - + + + + {{ yml['header'] | safe }} + {% if yml['css']['item'] %} + {% for css in yml['css']['item'] %} + + {% endfor %} + {% endif %} + {% if yml['js']['head'] %} + {% for js in yml['js']['head'] %} + + {% endfor %} + {% endif %} - + +
+
重置选中用户密码
+
+
+ + +
+ +
- -
-
重置选中用户密码
-
-
- - -
- - -
-
- -
- {% if tips %} +
+ {% if tips %} - {% endif %} + {% endif %} +
+
录入文章
+
+
+ + + -
-
录入文章
- -
- - - + + - - - - -
- - - + +
+ + +
-
-
-
文章列表
-
- {% for text in text_list %} +
+
文章列表
+
+ {% for text in text_list %}
-
{{ text['source'] }}
- Date:{{ text['date'] }} Level:{{ text['level'] }} +
{{ text.source }}
+ Date:{{ text.date }} Level:{{ text.level }}
-

{{ text['text'] }}

+ +

{{ text.text }}

- {% endfor %} - + {% endfor %} +
+
+
+
    +
  • Previous +
  • + {% for i in range(1, text_len//page_size+1) %} + {% if cur_page == i %} +
  • {{ i }} +
  • + {% else %} +
  • {{ i }}
  • + {% endif %} + {% endfor %} +
  • Next +
  • +
-
- - - - - - + \ No newline at end of file From b80fbc936c46bca7075e18f0abb428f5ced1e8b4 Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Mon, 20 Mar 2023 20:19:56 +0800 Subject: [PATCH 27/70] fix: fix admin_name --- app/admin_service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/admin_service.py b/app/admin_service.py index 87d2610..23c1544 100644 --- a/app/admin_service.py +++ b/app/admin_service.py @@ -7,7 +7,7 @@ from datetime import datetime # ? from difficulty import text_difficulty_level -ADMIN_NAME = "114514" # unique admin name +ADMIN_NAME = "lanhui" # unique admin name _cur_page = 1 # current article page _page_size = 5 # article sizes per page adminService = Blueprint("admin_service", __name__) From 70d44fcf5c913e9d1f5a2c4d33c906e2a8a9935d Mon Sep 17 00:00:00 2001 From: Lan Hui <1348141770@qq.com> Date: Tue, 21 Mar 2023 11:44:05 +0800 Subject: [PATCH 28/70] Login.py: fix SyntaxWrning: 'is not' with a literal. --- app/Login.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Login.py b/app/Login.py index f914359..48dffc5 100644 --- a/app/Login.py +++ b/app/Login.py @@ -96,7 +96,7 @@ class UserName: if ' ' in self.username: # a user name must not include a whitespace return 'Whitespace is not allowed in the user name.' for c in self.username: # a user name must not include special characters, except non-leading periods or underscores - if c in string.punctuation and c is not '.' and c is not '_': + if c in string.punctuation and c != '.' and c != '_': return f'{c} is not allowed in the user name.' if self.username in ['signup', 'login', 'logout', 'reset', 'mark', 'back', 'unfamiliar', 'familiar', 'del', "admin"]: return 'You used a restricted word as your user name. Please come up with a better one.' From b34f260d98309eea6819e57d9bf6dec6832cc9dd Mon Sep 17 00:00:00 2001 From: Lan Hui <1348141770@qq.com> Date: Tue, 21 Mar 2023 11:48:09 +0800 Subject: [PATCH 29/70] requirements.txt: use an older version of Flask to avoid deployment ERROR: No matching distribution found for Flask==2.1.0. --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 1972e7d..e2d1e1f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Flask==2.1.0 +Flask==1.1.2 selenium==3.141.0 PyYAML~=6.0 pony==0.7.16 From cabf6702a7428ab742345946e021fde904938bcd Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Mon, 20 Mar 2023 23:37:27 +0800 Subject: [PATCH 30/70] fix: add one way to set article level & rename some functions and vars --- app/admin_service.py | 35 +++++++++++++++++----------------- app/templates/admin_index.html | 6 +++--- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/app/admin_service.py b/app/admin_service.py index 23c1544..a06c838 100644 --- a/app/admin_service.py +++ b/app/admin_service.py @@ -5,8 +5,6 @@ from Yaml import yml from Login import md5 from datetime import datetime -# ? from difficulty import text_difficulty_level - ADMIN_NAME = "lanhui" # unique admin name _cur_page = 1 # current article page _page_size = 5 # article sizes per page @@ -25,19 +23,19 @@ def admin(): if username != ADMIN_NAME: return "You are not admin!" - article_len = get_articles_len() + article_number = get_number_of_articles() try: - _page_size = min(int(request.args.get("size", 5)), article_len) + _page_size = min(int(request.args.get("size", 5)), article_number) if _page_size <= 0: raise ZeroDivisionError - _cur_page = min(int(request.args.get("page", 1)), article_len // _page_size) + _cur_page = min(int(request.args.get("page", 1)), article_number // _page_size) except ValueError: return "page parmas must be int!" except ZeroDivisionError: return "page size must bigger than zero" context = { - "text_len": article_len, + "article_number": article_number, "page_size": _page_size, "cur_page": _cur_page, "text_list": get_page_articles(_cur_page, _page_size), @@ -47,8 +45,8 @@ def admin(): } def _update_context(): - article_len = get_articles_len() - context["text_len"] = article_len + article_len = get_number_of_articles() + context["article_number"] = article_len context["text_list"] = get_page_articles(_cur_page, _page_size) if request.method == "GET": @@ -61,8 +59,14 @@ def admin(): source = data.get("source", "") question = data.get("question", "") username = data.get("username", "") + level = data.get("level", "5") if content: - add_article(content, source, question) + try: # check level + if not (0 < int(level) <= 5): + raise ValueError + except ValueError: + return "level must be between 1 and 5" + add_article(content, source, level, question) _update_context() if username: update_user_password(username) @@ -70,21 +74,16 @@ def admin(): return render_template("admin_index.html", **context) -def add_article(content, source="manual_input", question="No question"): +def add_article(content, source="manual_input", level="5", question="No question"): with db_session: - # add one atricle to sqlite + # add one article to sqlite Article( text=content, source=source, date=datetime.now().strftime("%-d %b %Y"), # format style of `5 Oct 2022` - level="1", + level=level, question=question, ) - # ? There is a question that: - # ? How can i get one article level? - # ? I try to use the function `text_difficulty_level(content,{"test":1})` - # ? However, i lose one dict parma from pickle - # ? So I temporarily fixed the level to 1 def delete_article(article_id): @@ -94,7 +93,7 @@ def delete_article(article_id): article.first().delete() -def get_articles_len(): +def get_number_of_articles(): with db_session: return len(Article.select()[:]) diff --git a/app/templates/admin_index.html b/app/templates/admin_index.html index 03d6ee4..985ece0 100644 --- a/app/templates/admin_index.html +++ b/app/templates/admin_index.html @@ -70,10 +70,10 @@ - + + -
@@ -103,7 +103,7 @@
  • Previous
  • - {% for i in range(1, text_len//page_size+1) %} + {% for i in range(1, article_number//page_size+1) %} {% if cur_page == i %}
  • {{ i }}
  • From 1015704e23969506bef99745d6e3d28c1cf4ec90 Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Tue, 21 Mar 2023 12:29:44 +0800 Subject: [PATCH 31/70] fix: fix the way to check article level --- app/admin_service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/admin_service.py b/app/admin_service.py index a06c838..2ed9768 100644 --- a/app/admin_service.py +++ b/app/admin_service.py @@ -62,7 +62,7 @@ def admin(): level = data.get("level", "5") if content: try: # check level - if not (0 < int(level) <= 5): + if level not in [str(x + 1) for x in range(5)]: raise ValueError except ValueError: return "level must be between 1 and 5" From 48de496caa31ebfa6294beb7ca62917566ea1c18 Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Tue, 21 Mar 2023 12:42:59 +0800 Subject: [PATCH 32/70] fix: Remove 'Assignment Expresions' & Fix annotation words --- app/admin_service.py | 11 +++++++---- app/model.py | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/admin_service.py b/app/admin_service.py index 2ed9768..2893434 100644 --- a/app/admin_service.py +++ b/app/admin_service.py @@ -50,7 +50,8 @@ def admin(): context["text_list"] = get_page_articles(_cur_page, _page_size) if request.method == "GET": - if delete_id := int(request.args.get("delete_id", 0)): # delete article + delete_id = int(request.args.get("delete_id", 0)) + if delete_id: # delete article delete_article(delete_id) _update_context() else: @@ -89,7 +90,8 @@ def add_article(content, source="manual_input", level="5", question="No question def delete_article(article_id): article_id &= 0xFFFFFFFF # max 32 bits with db_session: - if article := Article.select(article_id=article_id): + article = Article.select(article_id=article_id) + if article: article.first().delete() @@ -113,5 +115,6 @@ def get_users(): def update_user_password(username, password="123456"): with db_session: - if user := User.select(name=username).first(): - user.password = md5(username + password) + user = User.select(name=username) + if user and user.first(): + user.first().password = md5(username + password) diff --git a/app/model.py b/app/model.py index a913e65..bc8a08a 100644 --- a/app/model.py +++ b/app/model.py @@ -1,7 +1,7 @@ from pony.orm import * db = Database() -db.bind("sqlite", "./static/wordfreqapp.db", create_db=True) # bind sqlit file +db.bind("sqlite", "./static/wordfreqapp.db", create_db=True) # bind sqlite file class User(db.Entity): From 44db2218c1636291f00dabba9e04fad965a783d6 Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Tue, 21 Mar 2023 12:45:57 +0800 Subject: [PATCH 33/70] fix: Use better conditional judgment methods --- app/admin_service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/admin_service.py b/app/admin_service.py index 2893434..95e9d8b 100644 --- a/app/admin_service.py +++ b/app/admin_service.py @@ -116,5 +116,5 @@ def get_users(): def update_user_password(username, password="123456"): with db_session: user = User.select(name=username) - if user and user.first(): + if user: user.first().password = md5(username + password) From 691c5b0d437694300bfb7823803054cb631701b5 Mon Sep 17 00:00:00 2001 From: Hui Lan Date: Tue, 21 Mar 2023 16:07:10 +0800 Subject: [PATCH 34/70] build.sh: Install requirements first. --- app/admin_service.py | 2 +- build.sh | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/admin_service.py b/app/admin_service.py index 23c1544..e014ee0 100644 --- a/app/admin_service.py +++ b/app/admin_service.py @@ -114,5 +114,5 @@ def get_users(): def update_user_password(username, password="123456"): with db_session: - if user := User.select(name=username).first(): + if if user := User.select(name=username).first(): user.password = md5(username + password) diff --git a/build.sh b/build.sh index 4348b2f..e313fce 100755 --- a/build.sh +++ b/build.sh @@ -3,6 +3,10 @@ DEPLOYMENT_DIR=/home/lanhui/englishpal2/EnglishPal cd $DEPLOYMENT_DIR +# Install dependencies + +pip3 install -r requirements.txt + # Stop service sudo docker stop EnglishPal sudo docker rm EnglishPal From 2909b4d9735f41d60b23893af3a89a32aa3174b6 Mon Sep 17 00:00:00 2001 From: Hui Lan Date: Tue, 21 Mar 2023 16:22:45 +0800 Subject: [PATCH 35/70] =?UTF-8?q?admin=5Fservice.py:=20=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=91=98=E9=A1=B5=E9=9D=A2=E6=98=BE=E7=A4=BA=E7=9A=84=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=90=8D=E6=8C=89=E7=85=A7=E5=90=8D=E5=AD=97=E6=8E=92?= =?UTF-8?q?=E5=BA=8F=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin_service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/admin_service.py b/app/admin_service.py index 95e9d8b..de05b46 100644 --- a/app/admin_service.py +++ b/app/admin_service.py @@ -110,7 +110,7 @@ def get_page_articles(num, size): def get_users(): with db_session: - return User.select()[:] + return User.select().order_by(User.name)[:] def update_user_password(username, password="123456"): From 6df25c58b400be6bc1820c5e76995caac9a7576b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E9=97=AE=E4=B8=89=E4=B8=8D=E7=9F=A5?= <178428409@qq.com> Date: Tue, 21 Mar 2023 18:57:00 +0800 Subject: [PATCH 36/70] =?UTF-8?q?=E6=9F=A5=E6=BC=8F=EF=BC=8C=E4=B8=9A?= =?UTF-8?q?=E5=8A=A1=E4=B8=AD=E7=9A=84=E4=B8=A4=E5=A4=84=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E4=B8=8D=E5=81=9A=E4=BF=AE=E6=94=B9=EF=BC=8C?= =?UTF-8?q?=E5=9B=A0=E4=B8=BA=E4=B8=8D=E8=A2=AB=E4=BD=BF=E7=94=A8=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/user_service.py | 2 +- app/wordfreqCMD.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/user_service.py b/app/user_service.py index 2c91391..8944b59 100644 --- a/app/user_service.py +++ b/app/user_service.py @@ -92,7 +92,7 @@ def deleteword(username, word): ''' user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) pickle_idea2.deleteRecord(user_freq_record, word) - flash(f'{word} is no longer in your word list.') + flash(f'{word} is no longer in your word list.') # 模板 userpage_get.html 中已经没有对flash信息的获取了,就不做修改了 return "success" diff --git a/app/wordfreqCMD.py b/app/wordfreqCMD.py index c4f8a63..e56ba0c 100644 --- a/app/wordfreqCMD.py +++ b/app/wordfreqCMD.py @@ -70,7 +70,7 @@ def sort_in_ascending_order(lst):# 单词按频率降序排列 return lst2 -def make_html_page(lst, fname): +def make_html_page(lst, fname): # 只是在wordfreqCMD.py中的main函数中调用,所以不做修改 ''' 功能:把lst的信息存到fname中,以html格式。 ''' From c9bfa086589fbcad05dc6ff46c64dafafede21d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E9=97=AE=E4=B8=89=E4=B8=8D=E7=9F=A5?= <178428409@qq.com> Date: Tue, 21 Mar 2023 19:19:51 +0800 Subject: [PATCH 37/70] =?UTF-8?q?=E6=B3=A8=E9=87=8Aflash=E7=9A=84=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=EF=BC=8C=E5=9B=A0=E4=B8=BA=E5=85=B6=E5=AF=B9=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E4=BC=9A=E6=9C=89=E5=BD=B1=E5=93=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/user_service.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/user_service.py b/app/user_service.py index 8944b59..94a522a 100644 --- a/app/user_service.py +++ b/app/user_service.py @@ -92,7 +92,8 @@ def deleteword(username, word): ''' user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) pickle_idea2.deleteRecord(user_freq_record, word) - flash(f'{word} is no longer in your word list.') # 模板 userpage_get.html 中已经没有对flash信息的获取了,就不做修改了 + # 模板 userpage_get.html 中已经没有对flash信息的获取了,而且会影响 signup.html的显示,因为其中去获取了flash。在删除单词,退出,注册,页面就会出现提示信息 + # flash(f'{word} is no longer in your word list.') return "success" From 5cffa1fadae10e01256d961faa93fe9eccca1984 Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Thu, 23 Mar 2023 13:32:11 +0800 Subject: [PATCH 38/70] fix: use single quotation mark 'admin' --- app/Login.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Login.py b/app/Login.py index 48dffc5..db4df18 100644 --- a/app/Login.py +++ b/app/Login.py @@ -98,7 +98,7 @@ class UserName: for c in self.username: # a user name must not include special characters, except non-leading periods or underscores if c in string.punctuation and c != '.' and c != '_': return f'{c} is not allowed in the user name.' - if self.username in ['signup', 'login', 'logout', 'reset', 'mark', 'back', 'unfamiliar', 'familiar', 'del', "admin"]: + if self.username in ['signup', 'login', 'logout', 'reset', 'mark', 'back', 'unfamiliar', 'familiar', 'del', 'admin']: return 'You used a restricted word as your user name. Please come up with a better one.' return 'OK' From 52025d55bc5c6ef7d5ecfcc79dbca87f2bf1c4c7 Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Thu, 23 Mar 2023 13:35:10 +0800 Subject: [PATCH 39/70] fix: add a blankspace --- app/templates/userpage_get.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/userpage_get.html b/app/templates/userpage_get.html index efb55da..94bfef1 100644 --- a/app/templates/userpage_get.html +++ b/app/templates/userpage_get.html @@ -37,7 +37,7 @@

    English Pal for {{ username }} - {% if username == admin_name%} + {% if username == admin_name %} 管理 {% endif %} 退出 From bdda754af6d718b95384240d9ecfc5e0eb1e343d Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Thu, 23 Mar 2023 13:40:22 +0800 Subject: [PATCH 40/70] fix: check current user is admin --- app/main.py | 11 ++++++++--- app/templates/mainpage_get.html | 7 +++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/main.py b/app/main.py index 2af57e3..e134da2 100644 --- a/app/main.py +++ b/app/main.py @@ -11,7 +11,7 @@ from Article import * import Yaml from user_service import userService from account_service import accountService -from admin_service import adminService +from admin_service import adminService, ADMIN_NAME app = Flask(__name__) app.secret_key = 'lunch.time!' @@ -98,8 +98,13 @@ def mainpage(): d = load_freq_history(path_prefix + 'static/frequency/frequency.p') d_len = len(d) lst = sort_in_descending_order(pickle_idea.dict2lst(d)) - return render_template('mainpage_get.html', random_ads=random_ads, number_of_essays=number_of_essays, - d_len=d_len, lst=lst, yml=Yaml.yml) + return render_template('mainpage_get.html', + admin_name=ADMIN_NAME, + random_ads=random_ads, + d_len=d_len, + lst=lst, + yml=Yaml.yml, + number_of_essays=number_of_essays) if __name__ == '__main__': diff --git a/app/templates/mainpage_get.html b/app/templates/mainpage_get.html index 4cc4417..15da6c4 100644 --- a/app/templates/mainpage_get.html +++ b/app/templates/mainpage_get.html @@ -23,12 +23,15 @@

    English Pal - Learn English smartly!

    {% if session['logged_in'] %} - {{session['username']}} 管理

    + {{ session['username'] }} + {% if session['username'] == admin_name %} + 管理

    + {% endif %} {% else %}

    管理 登录 注册 使用说明

    {{random_ads|safe}}

    {% endif %} - +

    粘贴1篇文章 (English only)


    From ec6a2249ae32f7748e5d0d231e27042ed6fca39b Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Thu, 23 Mar 2023 13:47:53 +0800 Subject: [PATCH 41/70] fix: fix the pagination --- app/admin_service.py | 8 ++------ app/templates/admin_index.html | 10 +++++----- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/app/admin_service.py b/app/admin_service.py index de05b46..717d4b4 100644 --- a/app/admin_service.py +++ b/app/admin_service.py @@ -25,14 +25,10 @@ def admin(): article_number = get_number_of_articles() try: - _page_size = min(int(request.args.get("size", 5)), article_number) - if _page_size <= 0: - raise ZeroDivisionError - _cur_page = min(int(request.args.get("page", 1)), article_number // _page_size) + _page_size = min(max(1, int(request.args.get("size", 5))), article_number) # 最小的size是1 + _cur_page = min(max(1, int(request.args.get("page", 1))), article_number // _page_size + 1) # 最小的page是1 except ValueError: return "page parmas must be int!" - except ZeroDivisionError: - return "page size must bigger than zero" context = { "article_number": article_number, diff --git a/app/templates/admin_index.html b/app/templates/admin_index.html index 985ece0..ed5eecd 100644 --- a/app/templates/admin_index.html +++ b/app/templates/admin_index.html @@ -101,17 +101,17 @@
    From 13ccbaf25c489d491f3f62228445c5287d033a69 Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Thu, 23 Mar 2023 13:58:11 +0800 Subject: [PATCH 42/70] fix: use select to choose article level --- app/templates/admin_index.html | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/app/templates/admin_index.html b/app/templates/admin_index.html index ed5eecd..5bc5901 100644 --- a/app/templates/admin_index.html +++ b/app/templates/admin_index.html @@ -45,7 +45,7 @@
    重置选中用户密码
    - + - + - - - + + +
    From 82896de3368c5002475f1031599e2b5d25f94392 Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Thu, 23 Mar 2023 16:21:02 +0800 Subject: [PATCH 43/70] update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 413c71c..3d901ba 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ app/static/frequency/frequency.p app/static/wordfreqapp.db app/static/donate-the-author.jpg app/static/donate-the-author-hidden.jpg +app/model/__pycache__/ \ No newline at end of file From 3e35679a91515425ec77573dc9a710860081dd2a Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Thu, 23 Mar 2023 17:09:25 +0800 Subject: [PATCH 44/70] refactor: refactor the model --- app/{model.py => model/__init__.py} | 2 +- app/model/article.py | 34 +++++++++++++++++++++++++++++ app/model/user.py | 19 ++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) rename app/{model.py => model/__init__.py} (89%) create mode 100644 app/model/article.py create mode 100644 app/model/user.py diff --git a/app/model.py b/app/model/__init__.py similarity index 89% rename from app/model.py rename to app/model/__init__.py index bc8a08a..9526313 100644 --- a/app/model.py +++ b/app/model/__init__.py @@ -1,7 +1,7 @@ from pony.orm import * db = Database() -db.bind("sqlite", "./static/wordfreqapp.db", create_db=True) # bind sqlite file +db.bind("sqlite", "../static/wordfreqapp.db", create_db=True) # bind sqlite file class User(db.Entity): diff --git a/app/model/article.py b/app/model/article.py new file mode 100644 index 0000000..a3b4bf7 --- /dev/null +++ b/app/model/article.py @@ -0,0 +1,34 @@ +from model import * +from datetime import datetime + +def add_article(content, source="manual_input", level="5", question="No question"): + with db_session: + # add one article to sqlite + Article( + text=content, + source=source, + date=datetime.now().strftime("%-d %b %Y"), # format style of `5 Oct 2022` + level=level, + question=question, + ) + + +def delete_article_by_id(article_id): + article_id &= 0xFFFFFFFF # max 32 bits + with db_session: + article = Article.select(article_id=article_id) + if article: + article.first().delete() + + +def get_number_of_articles(): + with db_session: + return len(Article.select()[:]) + + +def get_page_articles(num, size): + with db_session: + return [ + x + for x in Article.select().order_by(desc(Article.article_id)).page(num, size) + ] diff --git a/app/model/user.py b/app/model/user.py new file mode 100644 index 0000000..6c030c2 --- /dev/null +++ b/app/model/user.py @@ -0,0 +1,19 @@ +from model import * +from Login import md5 + +def get_users(): + with db_session: + return User.select().order_by(User.name)[:] + + +def update_password_by_username(username, password="123456"): + with db_session: + user = User.select(name=username) + if user: + user.first().password = md5(username + password) + +def update_expiry_time_by_username(username, expiry_time="20230323"): + with db_session: + user = User.select(name=username) + if user: + user.first().expiry_date = expiry_time From 2cf65123e9f06f7fc63caefd04db32d644e0e713 Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Thu, 23 Mar 2023 17:12:23 +0800 Subject: [PATCH 45/70] feat: admin can manage articles and users without interfering with each other --- app/admin_service.py | 141 ++++++++++++------------ app/templates/admin_index.html | 81 ++------------ app/templates/admin_manage_article.html | 99 +++++++++++++++++ app/templates/admin_manage_user.html | 83 ++++++++++++++ 4 files changed, 260 insertions(+), 144 deletions(-) create mode 100644 app/templates/admin_manage_article.html create mode 100644 app/templates/admin_manage_user.html diff --git a/app/admin_service.py b/app/admin_service.py index 717d4b4..35e032c 100644 --- a/app/admin_service.py +++ b/app/admin_service.py @@ -1,9 +1,10 @@ +# System Library from flask import * -from model import * -from pony.orm import * + +# Personal library from Yaml import yml -from Login import md5 -from datetime import datetime +from model.user import * +from model.article import * ADMIN_NAME = "lanhui" # unique admin name _cur_page = 1 # current article page @@ -11,33 +12,54 @@ _page_size = 5 # article sizes per page adminService = Blueprint("admin_service", __name__) -@adminService.route("/admin", methods=["GET", "POST"]) -def admin(): - global _cur_page, _page_size +def check_is_admin(): # 未登录,跳转到未登录界面 if not session.get("logged_in"): return render_template("not_login.html") - # 获取session里的用户名 - username = session.get("username") - if username != ADMIN_NAME: + # 用户名不是admin_name + if session.get("username") != ADMIN_NAME: return "You are not admin!" + return "pass" + + +@adminService.route("/admin", methods=["GET"]) +def admin(): + is_admin = check_is_admin() + if is_admin != "pass": + return is_admin + + return render_template( + "admin_index.html", yml=yml, username=session.get("username") + ) + + +@adminService.route("/admin/article", methods=["GET", "POST"]) +def article(): + global _cur_page, _page_size + + is_admin = check_is_admin() + if is_admin != "pass": + return is_admin + article_number = get_number_of_articles() try: - _page_size = min(max(1, int(request.args.get("size", 5))), article_number) # 最小的size是1 - _cur_page = min(max(1, int(request.args.get("page", 1))), article_number // _page_size + 1) # 最小的page是1 + _page_size = min( + max(1, int(request.args.get("size", 5))), article_number + ) # 最小的size是1 + _cur_page = min( + max(1, int(request.args.get("page", 1))), article_number // _page_size + 1 + ) # 最小的page是1 except ValueError: return "page parmas must be int!" context = { "article_number": article_number, + "text_list": get_page_articles(_cur_page, _page_size), "page_size": _page_size, "cur_page": _cur_page, - "text_list": get_page_articles(_cur_page, _page_size), - "user_list": get_users(), - "username": username, - "yml": yml, + "username": session.get("username"), } def _update_context(): @@ -46,71 +68,50 @@ def admin(): context["text_list"] = get_page_articles(_cur_page, _page_size) if request.method == "GET": - delete_id = int(request.args.get("delete_id", 0)) + try: + delete_id = int(request.args.get("delete_id", 0)) + except: + return "Delete article ID must be int!" if delete_id: # delete article - delete_article(delete_id) + delete_article_by_id(delete_id) _update_context() - else: + elif request.method == "POST": data = request.form content = data.get("content", "") source = data.get("source", "") question = data.get("question", "") - username = data.get("username", "") level = data.get("level", "5") if content: - try: # check level + try: # check level if level not in [str(x + 1) for x in range(5)]: raise ValueError except ValueError: - return "level must be between 1 and 5" + return "Level must be between 1 and 5" add_article(content, source, level, question) _update_context() + + return render_template("admin_manage_article.html", **context) + + +@adminService.route("/admin/user", methods=["GET", "POST"]) +def user(): + is_admin = check_is_admin() + if is_admin != "pass": + return is_admin + + context = { + "user_list": get_users(), + "username": session.get("username"), + } + if request.method == "POST": + data = request.form + username = data.get("username","") + new_password = data.get("new_password", "") + expiry_time = data.get("expiry_time", "") if username: - update_user_password(username) - - return render_template("admin_index.html", **context) - - -def add_article(content, source="manual_input", level="5", question="No question"): - with db_session: - # add one article to sqlite - Article( - text=content, - source=source, - date=datetime.now().strftime("%-d %b %Y"), # format style of `5 Oct 2022` - level=level, - question=question, - ) - - -def delete_article(article_id): - article_id &= 0xFFFFFFFF # max 32 bits - with db_session: - article = Article.select(article_id=article_id) - if article: - article.first().delete() - - -def get_number_of_articles(): - with db_session: - return len(Article.select()[:]) - - -def get_page_articles(num, size): - with db_session: - return [ - x - for x in Article.select().order_by(desc(Article.article_id)).page(num, size) - ] - - -def get_users(): - with db_session: - return User.select().order_by(User.name)[:] - - -def update_user_password(username, password="123456"): - with db_session: - user = User.select(name=username) - if user: - user.first().password = md5(username + password) + if new_password: + update_password_by_username(username, new_password) + if expiry_time: + update_expiry_time_by_username(username, "".join(expiry_time.split("-"))) + + return render_template("admin_manage_user.html", **context) \ No newline at end of file diff --git a/app/templates/admin_index.html b/app/templates/admin_index.html index 5bc5901..4d3f436 100644 --- a/app/templates/admin_index.html +++ b/app/templates/admin_index.html @@ -42,82 +42,15 @@
    -
    重置选中用户密码
    - -
    - - -
    - - -
    - -
    - {% if tips %} - From e27985127adcb0dd0cae3f301fdc86a20fa0aeb0 Mon Sep 17 00:00:00 2001 From: Hui Lan Date: Thu, 23 Mar 2023 21:00:31 +0800 Subject: [PATCH 47/70] =?UTF-8?q?admin=5Fmanage=5Farticle.html:=20?= =?UTF-8?q?=E6=96=87=E7=AB=A0=E6=9C=80=E9=AB=98=E9=9A=BE=E5=BA=A6=E7=AD=89?= =?UTF-8?q?=E7=BA=A7=E6=98=AF4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/templates/admin_manage_article.html | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/templates/admin_manage_article.html b/app/templates/admin_manage_article.html index ed058de..0533517 100644 --- a/app/templates/admin_manage_article.html +++ b/app/templates/admin_manage_article.html @@ -49,8 +49,7 @@ - - + @@ -98,4 +97,4 @@
    - \ No newline at end of file + From b97210a9e0b8d261743baef2f453dea97fff9b6a Mon Sep 17 00:00:00 2001 From: Hui Lan Date: Thu, 23 Mar 2023 21:19:20 +0800 Subject: [PATCH 48/70] =?UTF-8?q?admin=5Fmanage=5Farticle.html:=20?= =?UTF-8?q?=E6=9B=B4=E4=B8=BA=E8=AF=A6=E7=BB=86=E7=9A=84=20placeholder=20?= =?UTF-8?q?=E5=86=85=E5=AE=B9.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/templates/admin_manage_article.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/templates/admin_manage_article.html b/app/templates/admin_manage_article.html index 0533517..ef1542c 100644 --- a/app/templates/admin_manage_article.html +++ b/app/templates/admin_manage_article.html @@ -41,9 +41,9 @@
    - + - + - +
    From 7eb276937aff00d0a42010ed1d1c0f772377f025 Mon Sep 17 00:00:00 2001 From: Hui Lan Date: Thu, 23 Mar 2023 21:54:21 +0800 Subject: [PATCH 49/70] =?UTF-8?q?admin=5Fmanage=5Fuser.html:=20=E5=B0=86?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E8=BF=87=E6=9C=9F=E6=97=B6=E9=97=B4=E8=AE=BE?= =?UTF-8?q?=E4=B8=BA365=E5=A4=A9=E4=BB=A5=E5=90=8E.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/templates/admin_manage_user.html | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/templates/admin_manage_user.html b/app/templates/admin_manage_user.html index 59e1766..1b3f0a0 100644 --- a/app/templates/admin_manage_user.html +++ b/app/templates/admin_manage_user.html @@ -52,7 +52,7 @@
    - +
    @@ -80,4 +80,12 @@ }) - \ No newline at end of file + + + + From a220450b038dfeaefca83d957b9811c22c7ab9a0 Mon Sep 17 00:00:00 2001 From: Hui Lan Date: Thu, 23 Mar 2023 22:05:36 +0800 Subject: [PATCH 50/70] =?UTF-8?q?mainpage=5Fget.html:=20=E9=A6=96=E9=A1=B5?= =?UTF-8?q?=E4=B8=8D=E6=98=BE=E7=A4=BA=E7=AE=A1=E7=90=86=E9=93=BE=E6=8E=A5?= =?UTF-8?q?=EF=BC=88=E5=8F=AF=E8=83=BD=E4=BC=9A=E5=AE=89=E5=85=A8=E7=82=B9?= =?UTF-8?q?=EF=BC=89.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/templates/mainpage_get.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/mainpage_get.html b/app/templates/mainpage_get.html index 15da6c4..0590eec 100644 --- a/app/templates/mainpage_get.html +++ b/app/templates/mainpage_get.html @@ -28,7 +28,7 @@ 管理

    {% endif %} {% else %} -

    管理 登录 注册 使用说明

    +

    登录 注册 使用说明

    {{random_ads|safe}}

    {% endif %} From 99aa4e0990b7d32756c92b9163c4ab83e5db021f Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Sat, 25 Mar 2023 20:41:09 +0800 Subject: [PATCH 51/70] fix: fix article title show --- app/admin_service.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/admin_service.py b/app/admin_service.py index 9cbb75e..0e2a308 100644 --- a/app/admin_service.py +++ b/app/admin_service.py @@ -70,6 +70,10 @@ def article(): article_len = get_number_of_articles() context["article_number"] = article_len context["text_list"] = get_page_articles(_cur_page, _page_size) + _articles = get_page_articles(_cur_page, _page_size) + for article in _articles: # 获取每篇文章的title + article.title = article.text.split("\n")[0] + context["text_list"] = _articles if request.method == "GET": try: From ce28a5bf65d9bf71f7ef5e6ac931b719dd09c5fa Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Sat, 25 Mar 2023 21:20:19 +0800 Subject: [PATCH 52/70] feat: auto select expiry_date when select user --- app/templates/admin_manage_user.html | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/app/templates/admin_manage_user.html b/app/templates/admin_manage_user.html index 1b3f0a0..99af604 100644 --- a/app/templates/admin_manage_user.html +++ b/app/templates/admin_manage_user.html @@ -36,7 +36,7 @@
    - {% for user in user_list %} @@ -78,6 +78,19 @@ let pwd = generatePassword(12) document.getElementById("new_password").value = pwd }) + // 选择用户后更新其过期时间 + function select_user() { + let cur_user = $('#username').val(); + {% for user in user_list %} + if (cur_user == "{{ user.name }}") { + const dateString = "{{ user.expiry_date }}" + const year = dateString.substr(0,4); + const month = dateString.substr(4,2); + const day = dateString.substr(6,2); + document.getElementById("expiry_date").value = year + '-' + month + '-' + day + } + {% endfor %} + } - - - From fb6d0b23ce5a23d593ed5c11211476e8bf0d0ce3 Mon Sep 17 00:00:00 2001 From: Hui Lan Date: Sat, 25 Mar 2023 22:21:49 +0800 Subject: [PATCH 55/70] =?UTF-8?q?admin=5Fmanage=5Fuser.html:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=20JavaScript=20=E5=87=BD=E6=95=B0=E5=90=8D.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/templates/admin_manage_user.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/templates/admin_manage_user.html b/app/templates/admin_manage_user.html index 32aa149..a3a1755 100644 --- a/app/templates/admin_manage_user.html +++ b/app/templates/admin_manage_user.html @@ -36,7 +36,7 @@
    - {% for user in user_list %} @@ -79,7 +79,7 @@ document.getElementById("new_password").value = pwd }) // 选择用户后更新其过期时间 - function select_user() { + function loadUserExpiryDate() { let cur_user = $('#username').val(); {% for user in user_list %} if (cur_user == "{{ user.name }}") { From 3bc61a602f1ae4d7675e75dbecc4a3616ce63dd5 Mon Sep 17 00:00:00 2001 From: Lan Hui <1348141770@qq.com> Date: Sun, 26 Mar 2023 09:44:39 +0800 Subject: [PATCH 56/70] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=87=E7=AB=A0?= =?UTF-8?q?=E6=88=90=E5=8A=9F=E5=90=8E=EF=BC=8C=E4=BF=AE=E6=94=B9=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=BF=A1=E6=81=AF=E6=88=90=E5=8A=9F=E5=90=8E=EF=BC=8C?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=98=BE=E7=A4=BA=E6=88=90=E5=8A=9F=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=EF=BC=88flash=20messages=EF=BC=89=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin_service.py | 8 +++++--- app/templates/admin_manage_article.html | 6 ++++++ app/templates/admin_manage_user.html | 6 ++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/admin_service.py b/app/admin_service.py index 92150bd..8632b43 100644 --- a/app/admin_service.py +++ b/app/admin_service.py @@ -97,7 +97,8 @@ def article(): return "Level must be between 1 and 5" add_article(content, source, level, question) _update_context() - + title = content.split('\n')[0] + flash(f'Article added. Title: {title}') return render_template("admin_manage_article.html", **context) @@ -119,7 +120,8 @@ def user(): if username: if new_password: update_password_by_username(username, new_password) + flash(f'Password updated to {new_password}') if expiry_time: update_expiry_time_by_username(username, "".join(expiry_time.split("-"))) - - return render_template("admin_manage_user.html", **context) \ No newline at end of file + flash(f'Expiry date updated to {expiry_time}.') + return render_template("admin_manage_user.html", **context) diff --git a/app/templates/admin_manage_article.html b/app/templates/admin_manage_article.html index 99c2ef6..7e476e6 100644 --- a/app/templates/admin_manage_article.html +++ b/app/templates/admin_manage_article.html @@ -30,6 +30,12 @@
    + {% for message in get_flashed_messages() %} + + {% endfor %} +
    {% if tips %} + {% for message in get_flashed_messages() %} + + {% endfor %} +
    重置选中用户的信息
    From 8d8b9197b614b595bbba1ecf95c189ea1389780c Mon Sep 17 00:00:00 2001 From: Lan Hui <1348141770@qq.com> Date: Sun, 26 Mar 2023 09:59:06 +0800 Subject: [PATCH 57/70] =?UTF-8?q?=E6=89=8B=E5=8A=A8=E8=BE=93=E5=85=A5?= =?UTF-8?q?=E7=9A=84=E6=96=87=E5=AD=97=E6=9C=80=E9=AB=98=E9=9A=BE=E5=BA=A6?= =?UTF-8?q?=E7=AD=89=E7=BA=A7=E6=98=AF4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin_service.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/admin_service.py b/app/admin_service.py index 8632b43..30d622f 100644 --- a/app/admin_service.py +++ b/app/admin_service.py @@ -88,13 +88,13 @@ def article(): content = data.get("content", "") source = data.get("source", "") question = data.get("question", "") - level = data.get("level", "5") + level = data.get("level", "4") if content: try: # check level - if level not in [str(x + 1) for x in range(5)]: + if level not in ['1', '2', '3', '4']: raise ValueError except ValueError: - return "Level must be between 1 and 5" + return "Level must be between 1 and 4." add_article(content, source, level, question) _update_context() title = content.split('\n')[0] From 4d99405bfaf2f87abdf4bfa1291083419c6df502 Mon Sep 17 00:00:00 2001 From: Lan Hui <1348141770@qq.com> Date: Sun, 26 Mar 2023 18:59:15 +0800 Subject: [PATCH 58/70] =?UTF-8?q?=E7=AE=80=E5=8C=96=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=91=98=E9=A1=B5=E9=9D=A2=E4=BF=A1=E6=81=AF=E3=80=82=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E9=80=80=E5=87=BA=E7=99=BB=E5=BD=95=E6=8C=89=E9=92=AE?= =?UTF-8?q?=EF=BC=8C=E5=8F=AF=E4=BB=A5=E8=BF=94=E5=9B=9E=E5=88=B0=E5=89=8D?= =?UTF-8?q?=E4=B8=80=E9=A1=B5=E5=90=8E=E5=86=8D=E9=80=80=E5=87=BA=EF=BC=8C?= =?UTF-8?q?=E4=B8=8D=E5=BD=B1=E5=93=8D=E4=BD=BF=E7=94=A8=E4=BD=93=E9=AA=8C?= =?UTF-8?q?=E3=80=82=E5=88=A0=E9=99=A4'=E7=AE=A1=E7=90=86=E5=91=98?= =?UTF-8?q?=E6=82=A8=E5=A5=BD'=E6=AC=A2=E8=BF=8E=E8=AF=8D=EF=BC=8C?= =?UTF-8?q?=E6=B2=A1=E5=95=A5=E6=84=8F=E4=B9=89=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/templates/admin_index.html | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/templates/admin_index.html b/app/templates/admin_index.html index 4d3f436..68ee68f 100644 --- a/app/templates/admin_index.html +++ b/app/templates/admin_index.html @@ -23,7 +23,6 @@
    {% endfor %}
    From 9eb5210d3f11211abe756597518d09b1cfd8f3e4 Mon Sep 17 00:00:00 2001 From: Lan Hui <1348141770@qq.com> Date: Sun, 26 Mar 2023 20:58:37 +0800 Subject: [PATCH 61/70] =?UTF-8?q?Level=E4=B8=8EDate=E7=9A=84=E5=86=92?= =?UTF-8?q?=E5=8F=B7=E5=90=8E=E9=9D=A2=E5=8A=A0=E4=B8=AA=E7=A9=BA=E6=A0=BC?= =?UTF-8?q?=EF=BC=8C=E4=BD=BF=E5=BE=97=E5=90=8E=E9=9D=A2=E7=9A=84=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E6=9B=B4=E5=8A=A0=E7=9C=8B=E5=BE=97=E6=B8=85=E6=A5=9A?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/templates/admin_manage_article.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/templates/admin_manage_article.html b/app/templates/admin_manage_article.html index e324b71..2b2b7a2 100644 --- a/app/templates/admin_manage_article.html +++ b/app/templates/admin_manage_article.html @@ -73,8 +73,8 @@
    {{ text.source }}
    - Level:{{text.level }} - Date:{{ text.date }} + Level: {{text.level }} + Date: {{ text.date }}

    {{ text.content }}

From d4ac7093859d400f77f24c7cf5b6d39dd67b2e9a Mon Sep 17 00:00:00 2001 From: Lan Hui <1348141770@qq.com> Date: Sun, 26 Mar 2023 21:05:05 +0800 Subject: [PATCH 62/70] =?UTF-8?q?=E5=B0=86=E5=88=A0=E9=99=A4=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E7=A7=BB=E5=88=B0=E7=AC=AC=E4=B8=80=E8=A1=8C=EF=BC=8C?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E5=9B=A0=E4=B8=BA=E6=96=87=E7=AB=A0=E7=9A=84?= =?UTF-8?q?=E6=A0=87=E9=A2=98=E8=BF=87=E9=95=BF=E8=B7=A8=E8=A1=8C=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E5=88=A0=E9=99=A4=E6=8C=89=E9=92=AE=E5=BD=A2=E7=8A=B6?= =?UTF-8?q?=E6=94=B9=E5=8F=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/templates/admin_manage_article.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/templates/admin_manage_article.html b/app/templates/admin_manage_article.html index 2b2b7a2..1a07133 100644 --- a/app/templates/admin_manage_article.html +++ b/app/templates/admin_manage_article.html @@ -66,10 +66,11 @@
{% for text in text_list %}
+
+ 删除 +
{{ text.title }}
- 删除
{{ text.source }}
From 0ce1c6eb6e5707ccfb47113b2c58c9961f2eae48 Mon Sep 17 00:00:00 2001 From: Lan Hui <1348141770@qq.com> Date: Sun, 26 Mar 2023 21:14:29 +0800 Subject: [PATCH 63/70] =?UTF-8?q?=E6=96=87=E7=AB=A0=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=EF=BC=9A=E6=AF=8F=E7=AF=87=E6=96=87=E7=AB=A0?= =?UTF-8?q?=E4=B8=AD=E4=BF=9D=E7=95=99=E6=8D=A2=E8=A1=8C=EF=BC=8C=E6=96=B9?= =?UTF-8?q?=E4=BE=BF=E6=9F=A5=E7=9C=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin_service.py | 2 +- app/templates/admin_manage_article.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/admin_service.py b/app/admin_service.py index 1899002..16e80db 100644 --- a/app/admin_service.py +++ b/app/admin_service.py @@ -57,7 +57,7 @@ def article(): _articles = get_page_articles(_cur_page, _page_size) for article in _articles: # 获取每篇文章的title article.title = article.text.split("\n")[0] - article.content = ''.join(article.text.split("\n")[1:]) + article.content = '
'.join(article.text.split("\n")[1:]) context = { "article_number": _article_number, diff --git a/app/templates/admin_manage_article.html b/app/templates/admin_manage_article.html index 1a07133..272b54e 100644 --- a/app/templates/admin_manage_article.html +++ b/app/templates/admin_manage_article.html @@ -77,7 +77,7 @@ Level: {{text.level }} Date: {{ text.date }}
-

{{ text.content }}

+ {{ text.content | safe }}
{% endfor %}
From 5b2f5199a82be7cdb7bb3ac57f7b54b5ea0f4034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E9=97=AE=E4=B8=89=E4=B8=8D=E7=9F=A5?= <178428409@qq.com> Date: Mon, 27 Mar 2023 14:28:54 +0800 Subject: [PATCH 64/70] =?UTF-8?q?1.=20=E5=8F=96=E6=B6=88userpage=5Fget.htm?= =?UTF-8?q?l=E4=B8=AD=E6=8F=90=E7=A4=BA=E5=88=A0=E9=99=A4=E5=8D=95?= =?UTF-8?q?=E8=AF=8D=E4=BF=A1=E6=81=AF=E7=9A=84=E4=BB=A3=E7=A0=81=20?= =?UTF-8?q?=E5=92=8C=20=E5=8F=96=E6=B6=88user=5Fservice.userpage=E4=B8=ADr?= =?UTF-8?q?ender=5Ftemplate=E7=9A=84flashed=5Fmessages=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E3=80=82=E5=9B=A0=E4=B8=BA=E5=88=A0=E9=99=A4=E5=8D=95=E8=AF=8D?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E5=B7=B2=E7=BB=8F=E6=98=AF=E5=BC=82=E6=AD=A5?= =?UTF-8?q?=E4=BA=86=EF=BC=8C=E8=80=8C=E6=8F=90=E7=A4=BA=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E7=9A=84=E5=87=BA=E7=8E=B0=E6=98=AF=E5=90=8C=E6=AD=A5=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=EF=BC=8C=E6=89=80=E4=BB=A5=E5=B0=B1=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=E4=BA=86=E4=BB=A3=E7=A0=81=E4=B8=94=E6=B2=A1=E6=9C=89=E4=BA=A7?= =?UTF-8?q?=E7=94=9F=E5=A4=AA=E5=A4=A7=E5=BD=B1=E5=93=8D=E3=80=82=202.=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8F=96=E6=B6=88user=5Fservice.deleteword?= =?UTF-8?q?=E4=B8=AD=E5=AF=B9=E6=B3=A8=E9=87=8Aflash=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=9A=84=E6=B3=A8=E9=87=8A=EF=BC=8C=E6=A0=B9=E6=8D=AE=E4=B8=8A?= =?UTF-8?q?=E4=B8=80=E6=AD=A5=E8=BF=9B=E8=A1=8C=E4=BA=86=E9=87=8D=E6=96=B0?= =?UTF-8?q?=E8=A7=A3=E9=87=8A=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/templates/userpage_get.html | 6 +++--- app/user_service.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/templates/userpage_get.html b/app/templates/userpage_get.html index 5ef86c7..c9a04c1 100644 --- a/app/templates/userpage_get.html +++ b/app/templates/userpage_get.html @@ -40,9 +40,9 @@ 退出 重设密码

- {% for message in messages %} - - {% endfor %} +{# {% for message in flashed_messages %}#} {# 根据user_service.userpage,取消了参数flashed_messages,因此注释了这段代码 #} +{# #} +{# {% endfor %}#} 下一篇 Next Article {% if session.get('existing_articles')[0] != None and session.get('existing_articles')[0] !=0 %} diff --git a/app/user_service.py b/app/user_service.py index 94a522a..1b47d74 100644 --- a/app/user_service.py +++ b/app/user_service.py @@ -92,8 +92,8 @@ def deleteword(username, word): ''' user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) pickle_idea2.deleteRecord(user_freq_record, word) - # 模板 userpage_get.html 中已经没有对flash信息的获取了,而且会影响 signup.html的显示,因为其中去获取了flash。在删除单词,退出,注册,页面就会出现提示信息 - # flash(f'{word} is no longer in your word list.') + # 模板userpage_get.html中删除单词是异步执行,而flash的信息后续是同步执行的,所以注释这段代码;同时如果这里使用flash但不提取信息,则会影响 signup.html的显示。bug复现:删除单词后,点击退出,点击注册,注册页面就会出现提示信息 + # flash(f'{word} is no longer in your word list.') return "success" @@ -140,7 +140,7 @@ def userpage(username): return render_template('userpage_get.html', username=username, session=session, - flashed_messages=get_flashed_messages(), + # flashed_messages=get_flashed_messages(), 仅有删除单词的时候使用到flash,而删除单词是异步执行,这里的信息提示是同步执行,所以就没有存在的必要了 today_article=today_article, d_len=len(d), lst3=lst3, From 0c16a4dc6f21849915cdad92c7189e37ccb9a289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E9=97=AE=E4=B8=89=E4=B8=8D=E7=9F=A5?= <178428409@qq.com> Date: Wed, 29 Mar 2023 20:53:38 +0800 Subject: [PATCH 65/70] =?UTF-8?q?=E5=88=A4=E6=96=AD=E6=96=87=E7=AB=A0?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E5=B7=B2=E7=BB=8F=E5=87=BA=E7=8E=B0=E7=9A=84?= =?UTF-8?q?=E8=AF=AD=E5=8F=A5=E5=86=99=E9=94=99=E4=BD=8D=E7=BD=AE=E4=BA=86?= =?UTF-8?q?=EF=BC=8C=E6=94=B9=E6=AD=A3=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Article.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Article.py b/app/Article.py index 707ad91..d67995b 100644 --- a/app/Article.py +++ b/app/Article.py @@ -59,7 +59,8 @@ def get_today_article(user_word_list, existing_articles): text_level = text_difficulty_level(reading['text'], d3) factor = random.gauss(0.8, 0.1) # a number drawn from Gaussian distribution with a mean of 0.8 and a stand deviation of 1 - if within_range(reading['article_id'] not in existing_articles[1] and text_level, user_level, (8.0 - user_level) * factor): # 新的文章之前没有出现过且符合一定范围的水平 + print("factor:{}, text_level:{}, user_level:{}, range:{}".format(factor, text_level, user_level, (8.0 - user_level) * factor)) + if reading['article_id'] not in existing_articles[1] and within_range(text_level, user_level, (8.0 - user_level) * factor): # 新的文章之前没有出现过且符合一定范围的水平 d = reading existing_articles[1].append(d['article_id']) # 列表添加新的文章id;下面进行 flag = True From 4417cf7017d50f20d99e1a274b48ad5d3b32e8e6 Mon Sep 17 00:00:00 2001 From: Hui Lan Date: Thu, 30 Mar 2023 16:10:22 +0800 Subject: [PATCH 66/70] Article.py: remove debug statement. --- app/Article.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/Article.py b/app/Article.py index d67995b..6281c38 100644 --- a/app/Article.py +++ b/app/Article.py @@ -59,7 +59,6 @@ def get_today_article(user_word_list, existing_articles): text_level = text_difficulty_level(reading['text'], d3) factor = random.gauss(0.8, 0.1) # a number drawn from Gaussian distribution with a mean of 0.8 and a stand deviation of 1 - print("factor:{}, text_level:{}, user_level:{}, range:{}".format(factor, text_level, user_level, (8.0 - user_level) * factor)) if reading['article_id'] not in existing_articles[1] and within_range(text_level, user_level, (8.0 - user_level) * factor): # 新的文章之前没有出现过且符合一定范围的水平 d = reading existing_articles[1].append(d['article_id']) # 列表添加新的文章id;下面进行 @@ -125,4 +124,4 @@ def get_answer_part(s): flag = 1 elif flag == 1: result.append(line) - return '\n'.join(result) \ No newline at end of file + return '\n'.join(result) From 6f1dd134193cb3f9fa1d3502b286d3be1f22c1ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E9=97=AE=E4=B8=89=E4=B8=8D=E7=9F=A5?= <178428409@qq.com> Date: Fri, 31 Mar 2023 04:50:41 +0800 Subject: [PATCH 67/70] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=9A=84print=E5=BF=98?= =?UTF-8?q?=E5=88=A0=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Article.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/Article.py b/app/Article.py index d67995b..32bb605 100644 --- a/app/Article.py +++ b/app/Article.py @@ -59,7 +59,6 @@ def get_today_article(user_word_list, existing_articles): text_level = text_difficulty_level(reading['text'], d3) factor = random.gauss(0.8, 0.1) # a number drawn from Gaussian distribution with a mean of 0.8 and a stand deviation of 1 - print("factor:{}, text_level:{}, user_level:{}, range:{}".format(factor, text_level, user_level, (8.0 - user_level) * factor)) if reading['article_id'] not in existing_articles[1] and within_range(text_level, user_level, (8.0 - user_level) * factor): # 新的文章之前没有出现过且符合一定范围的水平 d = reading existing_articles[1].append(d['article_id']) # 列表添加新的文章id;下面进行 From 1f150fc847d0fc70947261ff45843ccc116117c2 Mon Sep 17 00:00:00 2001 From: Awoodwhale Date: Fri, 31 Mar 2023 13:39:28 +0800 Subject: [PATCH 68/70] refactor: use ajax to get expiry_date --- app/admin_service.py | 17 +++++++++++++++++ app/model/user.py | 5 +++++ app/templates/admin_manage_user.html | 17 +++++++++-------- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/app/admin_service.py b/app/admin_service.py index 16e80db..efbaf6d 100644 --- a/app/admin_service.py +++ b/app/admin_service.py @@ -126,3 +126,20 @@ def user(): update_expiry_time_by_username(username, "".join(expiry_time.split("-"))) flash(f'Expiry date updated to {expiry_time}.') return render_template("admin_manage_user.html", **context) + + +@adminService.route("/admin/expiry", methods=["GET"]) +def user_expiry_time(): + is_admin = check_is_admin() + if is_admin != "pass": + return is_admin + + username = request.args.get("username", "") + if not username: + return "Username can't empty" + + user = get_user_by_username(username) + if not user: + return "User not exist" + + return user.expiry_date \ No newline at end of file diff --git a/app/model/user.py b/app/model/user.py index 6c030c2..28173b9 100644 --- a/app/model/user.py +++ b/app/model/user.py @@ -5,6 +5,11 @@ def get_users(): with db_session: return User.select().order_by(User.name)[:] +def get_user_by_username(username): + with db_session: + user = User.select(name=username) + if user: + return user.first() def update_password_by_username(username, password="123456"): with db_session: diff --git a/app/templates/admin_manage_user.html b/app/templates/admin_manage_user.html index 585fc82..a3f0ca0 100644 --- a/app/templates/admin_manage_user.html +++ b/app/templates/admin_manage_user.html @@ -82,16 +82,17 @@ }) // 选择用户后更新其过期时间 function loadUserExpiryDate() { - let cur_user = $('#username').val(); - {% for user in user_list %} - if (cur_user == "{{ user.name }}") { - const dateString = "{{ user.expiry_date }}" - const year = dateString.substr(0,4); - const month = dateString.substr(4,2); - const day = dateString.substr(6,2); + const cur_user = $('#username').val(); + $.ajax({ + type: "GET", + url: `/admin/expiry?username=${cur_user}`, + success: function(resp) { + const year = resp.substr(0,4); + const month = resp.substr(4,2); + const day = resp.substr(6,2); document.getElementById("expiry_date").value = year + '-' + month + '-' + day } - {% endfor %} + }) } From 688ed724734fddb4a07e9dd0dc5b6b2ace16e645 Mon Sep 17 00:00:00 2001 From: Lan Hui <1348141770@qq.com> Date: Sat, 1 Apr 2023 16:07:59 +0800 Subject: [PATCH 69/70] =?UTF-8?q?Correct=20grammar=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin_service.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/admin_service.py b/app/admin_service.py index efbaf6d..1d1ba6e 100644 --- a/app/admin_service.py +++ b/app/admin_service.py @@ -133,13 +133,13 @@ def user_expiry_time(): is_admin = check_is_admin() if is_admin != "pass": return is_admin - + username = request.args.get("username", "") if not username: - return "Username can't empty" - + return "Username can't be empty." + user = get_user_by_username(username) if not user: - return "User not exist" - - return user.expiry_date \ No newline at end of file + return "User does not exist." + + return user.expiry_date From 15bb9250248aa6feb249be72c53d3fa6d7005d52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E9=97=AE=E4=B8=89=E4=B8=8D=E7=9F=A5?= <178428409@qq.com> Date: Tue, 4 Apr 2023 22:31:53 +0800 Subject: [PATCH 70/70] =?UTF-8?q?=E5=B0=86=E8=AE=B0=E5=BD=95=E9=98=85?= =?UTF-8?q?=E8=AF=BB=E8=BF=87=E6=96=87=E7=AB=A0=E7=9A=84=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E6=94=B9=E4=B8=BA=E5=AD=97=E5=85=B8=EF=BC=8C?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=E4=BF=AE=E6=94=B9=E4=BA=86flag=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Article.py | 28 +++++++++++++++------------- app/templates/userpage_get.html | 2 +- app/user_service.py | 4 ++-- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/app/Article.py b/app/Article.py index 6281c38..e0f006a 100644 --- a/app/Article.py +++ b/app/Article.py @@ -35,11 +35,14 @@ def get_article_body(s): def get_today_article(user_word_list, existing_articles): rq = RecordQuery(path_prefix + 'static/wordfreqapp.db') if existing_articles is None: - existing_articles = [0, []] # existing_articles[0]:为existing_articles[1]的索引;existing_articles[1]:之前显示文章的id列表,越后越新 - if existing_articles[0] > len(existing_articles[1])-1: + existing_articles = { + "index" : 0, # 为 article_ids 的索引 + "article_ids": [] # 之前显示文章的id列表,越后越新 + } + if existing_articles["index"] > len(existing_articles["article_ids"])-1: rq.instructions("SELECT * FROM article") else: - rq.instructions('SELECT * FROM article WHERE article_id=%d' % (existing_articles[1][existing_articles[0]])) + rq.instructions('SELECT * FROM article WHERE article_id=%d' % (existing_articles["article_ids"][existing_articles["index"]])) rq.do() result = rq.get_results() random.shuffle(result) @@ -49,28 +52,29 @@ def get_today_article(user_word_list, existing_articles): d2 = load_freq_history(path_prefix + 'static/words_and_tests.p') d3 = get_difficulty_level(d1, d2) - d = {} + d = None d_user = load_freq_history(user_word_list) user_level = user_difficulty_level(d_user, d3) # more consideration as user's behaviour is dynamic. Time factor should be considered. text_level = 0 - flag = False - if existing_articles[0] > len(existing_articles[1])-1: # 下一篇 + if existing_articles["index"] > len(existing_articles["article_ids"])-1: # 下一篇 + flag_get_article = False for reading in result: text_level = text_difficulty_level(reading['text'], d3) factor = random.gauss(0.8, 0.1) # a number drawn from Gaussian distribution with a mean of 0.8 and a stand deviation of 1 - if reading['article_id'] not in existing_articles[1] and within_range(text_level, user_level, (8.0 - user_level) * factor): # 新的文章之前没有出现过且符合一定范围的水平 + if reading['article_id'] not in existing_articles["article_ids"] and within_range(text_level, user_level, (8.0 - user_level) * factor): # 新的文章之前没有出现过且符合一定范围的水平 d = reading - existing_articles[1].append(d['article_id']) # 列表添加新的文章id;下面进行 - flag = True + existing_articles["article_ids"].append(d['article_id']) # 列表添加新的文章id;下面进行 + flag_get_article = True break + if not flag_get_article: + existing_articles["index"] -= 1 else: # 上一篇 d = random.choice(result) text_level = text_difficulty_level(d['text'], d3) - flag = True today_article = None - if flag: + if d: today_article = { "user_level": '%4.2f' % user_level, "text_level": '%4.2f' % text_level, @@ -81,8 +85,6 @@ def get_today_article(user_word_list, existing_articles): "question": get_question_part(d['question']), "answer": get_answer_part(d['question']) } - else: - existing_articles[0] -= 1 return existing_articles, today_article diff --git a/app/templates/userpage_get.html b/app/templates/userpage_get.html index c9a04c1..298b559 100644 --- a/app/templates/userpage_get.html +++ b/app/templates/userpage_get.html @@ -45,7 +45,7 @@ {# {% endfor %}#} 下一篇 Next Article - {% if session.get('existing_articles')[0] != None and session.get('existing_articles')[0] !=0 %} + {% if session.get('existing_articles') != None and session.get('existing_articles')["index"] !=0 %} 上一篇 Previous Article {% endif %} diff --git a/app/user_service.py b/app/user_service.py index 1b47d74..8d1dbfc 100644 --- a/app/user_service.py +++ b/app/user_service.py @@ -31,7 +31,7 @@ def user_reset(username): ''' if request.method == 'GET': existing_articles = session.get("existing_articles") - existing_articles[0] += 1 + existing_articles["index"] += 1 session["existing_articles"] = existing_articles return redirect(url_for('user_bp.userpage', username=username)) else: @@ -46,7 +46,7 @@ def user_back(username): ''' if request.method == 'GET': existing_articles = session.get("existing_articles") - existing_articles[0] -= 1 + existing_articles["index"] -= 1 session["existing_articles"] = existing_articles return redirect(url_for('user_bp.userpage', username=username))