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 01/55] 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 74eccfbebd04899a08ff5d3ab56d41c0e83808bf Mon Sep 17 00:00:00 2001
From: xujiahui <1419417159@qq.com>
Date: Tue, 20 Dec 2022 19:55:02 +0800
Subject: [PATCH 02/55] =?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 %}
+
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 03/55] =?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 %}
+
+ {{ 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 %}
共有文章 {{number_of_essays}} 篇
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 04/55] 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 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 05/55] =?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 @@
1×
-
+
-
+
收集生词吧 (可以在正文中划词,也可以复制黏贴)
@@ -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 06/55] =?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 = '
According to your word list, your level is %4.2f and we have chosen an article with a difficulty level of %4.2f for you.
' % (
- 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 += 'ANSWER \n'
- html_code += '%s
\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 %}
共有文章 {{number_of_essays}} 篇
粘贴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 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #}
-
-{# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! #}
English Pal for {{ username }}
退出
重设密码
- {{ flashed_messages|safe }}
+ {% for message in messages %}
+
Congratulations! {{ message }}
+ {% 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 %}
+
According to your word list, your level is {{ today_article["user_level"] }} and we have chosen an article with a difficulty level of {{ today_article["text_level"] }} for you.
+
Article added on: {{ today_article["date"] }}
+
+
{{ today_article["article_title"] }}
+
{{ today_article["article_body"] }}
+
{{ today_article['source'] }}
+
{{ today_article['question'] }}
+
+
ANSWER
+
{{ today_article['answer'] }}
+
+ {% else %}
+
+
Notes: No article is currently available for you. You can try again a few times or mark new words in the passage to improve your level.
+
+ {% 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 += '
'
- s += f'Congratulations! {message}'
- 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 07/55] 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 08/55] 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 09/55] 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 10/55] 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 11/55] 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 %}
-
-
-
你好 {{ username }}
-
+
+
管理员 {{ username }} 您好!
+
-
-
-
+
+
+
+
重置选中用户密码
+
+
+ 用户
+
+ 选择用户
+ {% for user in user_list %}
+ {{ user.name }}
+ {% endfor %}
+
+
+
+
-
-
-
重置选中用户密码
-
-
- 用户
-
- 选择用户
- {% for user in user_list %}
- {{ user['name'] }}
- {% endfor %}
-
-
-
-
-
-
-
-
-
- {% if tips %}
+
+ {% if tips %}
{{ 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 %}
+
+
+
+
-
-
-
-
-
-
-
+
\ 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 12/55] 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 13/55] 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 14/55] 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 15/55] 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 @@