forked from mrlan/EnglishPal
Compare commits
23 Commits
bug555-fan
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
c64af4a20a | |
|
|
6285581bb5 | |
|
|
c9bbf6b6a3 | |
|
|
68e4ba33c5 | |
|
|
d9512c929b | |
|
|
ce58f14406 | |
|
|
05dc0ecbb7 | |
|
|
8859827eac | |
|
|
b6a36b1d1a | |
|
|
12752341db | |
|
|
3abebdfb21 | |
|
|
92331ca7a0 | |
|
|
1166d3499f | |
|
|
fe1d4c29ff | |
|
|
aaf2db8657 | |
|
|
e478217343 | |
|
|
4f95935037 | |
|
|
370a215d08 | |
|
|
de81f5966d | |
|
|
38206271c6 | |
|
|
172727f95f | |
|
|
46d1793397 | |
|
|
74186df292 |
|
|
@ -18,7 +18,7 @@ picked from articles selected for him to read according his vocabulary level. E
|
||||||
|
|
||||||
`python3 main.py`
|
`python3 main.py`
|
||||||
|
|
||||||
Make sure you have put the SQLite database file in the path `app/static` (see below).
|
Make sure you have put the SQLite database file in the path `app/db` (see below).
|
||||||
|
|
||||||
|
|
||||||
## Run it as a Docker container
|
## Run it as a Docker container
|
||||||
|
|
@ -214,5 +214,5 @@ 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
|
||||||
|
|
||||||
|
|
||||||
*Last modified on 2023-01-30*
|
*Last modified on 2026-03-12*
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ def get_today_article(user_word_list, visited_articles):
|
||||||
text_level = text_difficulty_level(d['text'], d3)
|
text_level = text_difficulty_level(d['text'], d3)
|
||||||
result_of_generate_article = "found"
|
result_of_generate_article = "found"
|
||||||
|
|
||||||
today_article = None
|
today_article = {}
|
||||||
if d:
|
if d:
|
||||||
oxford_words = load_oxford_words(oxford_words_path)
|
oxford_words = load_oxford_words(oxford_words_path)
|
||||||
oxford_word_count, total_words = count_oxford_words(d['text'],oxford_words)
|
oxford_word_count, total_words = count_oxford_words(d['text'],oxford_words)
|
||||||
|
|
|
||||||
13
app/Login.py
13
app/Login.py
|
|
@ -21,11 +21,6 @@ path_prefix = '/var/www/wordfreq/wordfreq/'
|
||||||
path_prefix = './' # comment this line in deployment
|
path_prefix = './' # comment this line in deployment
|
||||||
|
|
||||||
|
|
||||||
def verify_pass(newpass, oldpass):
|
|
||||||
if (newpass == oldpass):
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def verify_user(username, password):
|
def verify_user(username, password):
|
||||||
user = get_user_by_username(username)
|
user = get_user_by_username(username)
|
||||||
encoded_password = md5(username + password)
|
encoded_password = md5(username + password)
|
||||||
|
|
@ -54,12 +49,12 @@ def change_password(username, old_password, new_password):
|
||||||
:return: 修改成功:True 否则:False
|
:return: 修改成功:True 否则:False
|
||||||
'''
|
'''
|
||||||
if not verify_user(username, old_password): # 旧密码错误
|
if not verify_user(username, old_password): # 旧密码错误
|
||||||
return False
|
return {'error':'Old password is wrong.', 'username':username}
|
||||||
# 将用户名和密码一起加密,以免暴露不同用户的相同密码
|
# 将用户名和密码一起加密,以免暴露不同用户的相同密码
|
||||||
if verify_pass(new_password, old_password): #新旧密码一致
|
if new_password == old_password: #新旧密码一致
|
||||||
return False
|
return {'error':'New password cannot be the same as the old password.', 'username':username}
|
||||||
update_password_by_username(username, new_password)
|
update_password_by_username(username, new_password)
|
||||||
return True
|
return {'success':'Password changed', 'username':username}
|
||||||
|
|
||||||
|
|
||||||
def get_expiry_date(username):
|
def get_expiry_date(username):
|
||||||
|
|
|
||||||
|
|
@ -133,10 +133,7 @@ def reset():
|
||||||
# POST请求用于提交修改后信息
|
# POST请求用于提交修改后信息
|
||||||
old_password = escape(request.form['old-password'])
|
old_password = escape(request.form['old-password'])
|
||||||
new_password = escape(request.form['new-password'])
|
new_password = escape(request.form['new-password'])
|
||||||
flag = change_password(username, old_password, new_password) # flag表示是否修改成功
|
result = change_password(username, old_password, new_password)
|
||||||
if flag:
|
return jsonify(result)
|
||||||
session['logged_in'] = False
|
|
||||||
return jsonify({'status':'1'}) # 修改成功
|
|
||||||
else:
|
|
||||||
return jsonify({'status':'2'}) # 修改失败
|
|
||||||
|
|
||||||
|
|
|
||||||
13
app/main.py
13
app/main.py
|
|
@ -4,6 +4,7 @@
|
||||||
###########################################################################
|
###########################################################################
|
||||||
from flask import abort, jsonify
|
from flask import abort, jsonify
|
||||||
from markupsafe import escape
|
from markupsafe import escape
|
||||||
|
from collections import Counter
|
||||||
from Login import *
|
from Login import *
|
||||||
from Article import *
|
from Article import *
|
||||||
import Yaml
|
import Yaml
|
||||||
|
|
@ -58,6 +59,12 @@ def appears_in_test(word, d):
|
||||||
else:
|
else:
|
||||||
return ','.join(d[word])
|
return ','.join(d[word])
|
||||||
|
|
||||||
|
|
||||||
|
def good_word(word):
|
||||||
|
return len(word) < len('Pneumonoultramicroscopicsilicovolcanoconiosis') \
|
||||||
|
and Counter(word).most_common(1)[0][1] <= 4
|
||||||
|
|
||||||
|
|
||||||
@app.route("/mark", methods=['GET', 'POST'])
|
@app.route("/mark", methods=['GET', 'POST'])
|
||||||
def mark_word():
|
def mark_word():
|
||||||
'''
|
'''
|
||||||
|
|
@ -99,7 +106,7 @@ def mainpage():
|
||||||
if request.method == 'POST': # when we submit a form
|
if request.method == 'POST': # when we submit a form
|
||||||
content = escape(request.form['content'])
|
content = escape(request.form['content'])
|
||||||
f = WordFreq(content)
|
f = WordFreq(content)
|
||||||
lst = f.get_freq()
|
lst = [ t for t in f.get_freq() if good_word(t[0]) ] # only keep normal words
|
||||||
# save history
|
# save history
|
||||||
d = load_freq_history(path_prefix + 'static/frequency/frequency.p')
|
d = load_freq_history(path_prefix + 'static/frequency/frequency.p')
|
||||||
lst_history = pickle_idea.dict2lst(d)
|
lst_history = pickle_idea.dict2lst(d)
|
||||||
|
|
@ -137,8 +144,8 @@ if __name__ == '__main__':
|
||||||
运行程序
|
运行程序
|
||||||
'''
|
'''
|
||||||
# app.secret_key = os.urandom(16)
|
# app.secret_key = os.urandom(16)
|
||||||
# app.run(debug=False, port='6000')
|
app.run(debug=True, port=5000)
|
||||||
app.run(debug=True)
|
# app.run(debug=True)
|
||||||
# app.run(debug=True, port='6000')
|
# app.run(debug=True, port='6000')
|
||||||
# app.run(host='0.0.0.0', debug=True, port='6000')
|
# app.run(host='0.0.0.0', debug=True, port='6000')
|
||||||
# print(mod5('123'))
|
# print(mod5('123'))
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
# Purpose: dictionary & pickle as a simple means of database.
|
# Purpose: dictionary & pickle as a simple means of database.
|
||||||
# Task: incorporate the functions into wordfreqCMD.py such that it will also show cumulative frequency.
|
# Task: incorporate the functions into wordfreqCMD.py such that it will also show cumulative frequency.
|
||||||
|
|
||||||
|
import os
|
||||||
import pickle
|
import pickle
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
@ -55,10 +56,12 @@ def save_frequency_to_pickle(d, pickle_fname):
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
def unfamiliar(path,word):
|
def unfamiliar(path,word):
|
||||||
f = open(path,"rb")
|
if not os.path.exists(path):
|
||||||
|
return None
|
||||||
|
with open(path,"rb") as f:
|
||||||
dic = pickle.load(f)
|
dic = pickle.load(f)
|
||||||
dic[word] += [datetime.now().strftime('%Y%m%d%H%M')]
|
dic[word] += [datetime.now().strftime('%Y%m%d%H%M')]
|
||||||
fp = open(path,"wb")
|
with open(path,"wb") as fp:
|
||||||
pickle.dump(dic,fp)
|
pickle.dump(dic,fp)
|
||||||
|
|
||||||
def familiar(path,word):
|
def familiar(path,word):
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,6 @@ def load_record(pickle_fname):
|
||||||
|
|
||||||
def save_frequency_to_pickle(d, pickle_fname):
|
def save_frequency_to_pickle(d, pickle_fname):
|
||||||
f = open(pickle_fname, 'wb')
|
f = open(pickle_fname, 'wb')
|
||||||
exclusion_lst = ['one', 'no', 'has', 'had', 'do', 'that', 'have', 'by', 'not', 'but', 'we', 'this', 'my', 'him', 'so', 'or', 'as', 'are', 'it', 'from', 'with', 'be', 'can', 'for', 'an', 'if', 'who', 'whom', 'whose', 'which', 'the', 'to', 'a', 'of', 'and', 'you', 'i', 'he', 'she', 'they', 'me', 'was', 'were', 'is', 'in', 'at', 'on', 'their', 'his', 'her', 's', 'said', 'all', 'did', 'been', 'w']
|
|
||||||
d2 = {}
|
d2 = {}
|
||||||
for k in d:
|
for k in d:
|
||||||
if not k in exclusion_lst and not k.isnumeric() and not len(k) < 2:
|
if not k in exclusion_lst and not k.isnumeric() and not len(k) < 2:
|
||||||
|
|
@ -73,6 +72,7 @@ def save_frequency_to_pickle(d, pickle_fname):
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
exclusion_lst = ['one', 'no', 'has', 'had', 'do', 'that', 'have', 'by', 'not', 'but', 'we', 'this', 'my', 'him', 'so', 'or', 'as', 'are', 'it', 'from', 'with', 'be', 'can', 'for', 'an', 'if', 'who', 'whom', 'whose', 'which', 'the', 'to', 'a', 'of', 'and', 'you', 'i', 'he', 'she', 'they', 'me', 'was', 'were', 'is', 'in', 'at', 'on', 'their', 'his', 'her', 's', 'said', 'all', 'did', 'been', 'w']
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
function containsDigitsLettersSpecialCharacters(s) {
|
||||||
|
let resultD = 0, resultL = 0, resultS = 0;
|
||||||
|
|
||||||
|
// Digit test
|
||||||
|
'0123456789'.split('').forEach((x) => {
|
||||||
|
if (s.includes(x))
|
||||||
|
resultD = 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Letter test
|
||||||
|
resultL = /[a-z]/i.test(s);
|
||||||
|
|
||||||
|
// Special charater test
|
||||||
|
'+-*/,.:;/\[]<>$%&()!?^~'.split('').forEach((x) => {
|
||||||
|
if (s.includes(x))
|
||||||
|
resultS = 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
return resultD + resultL + resultS == 3;
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
function familiar(theWord) {
|
function familiar(theWord) {
|
||||||
let username = $("#username").text();
|
let username = $("#username").text();
|
||||||
let word = $("#word_" + theWord).text();
|
let word = document.getElementById(`word_${theWord}`).innerText;
|
||||||
let freq = $("#freq_" + theWord).text();
|
let freq = document.getElementById(`freq_${theWord}`).innerText;
|
||||||
|
console.log(theWord);
|
||||||
|
console.log(word);
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type:"GET",
|
type:"GET",
|
||||||
url:"/" + username + "/" + word + "/familiar",
|
url:"/" + username + "/" + word + "/familiar",
|
||||||
|
|
@ -27,8 +29,10 @@ function familiar(theWord) {
|
||||||
|
|
||||||
function unfamiliar(theWord) {
|
function unfamiliar(theWord) {
|
||||||
let username = $("#username").text();
|
let username = $("#username").text();
|
||||||
let word = $("#word_" + theWord).text();
|
let word = document.getElementById(`word_${theWord}`).innerText;
|
||||||
let freq = $("#freq_" + theWord).text();
|
let freq = document.getElementById(`freq_${theWord}`).innerText;
|
||||||
|
console.log(theWord);
|
||||||
|
console.log(word);
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type:"GET",
|
type:"GET",
|
||||||
url:"/" + username + "/" + word + "/unfamiliar",
|
url:"/" + username + "/" + word + "/unfamiliar",
|
||||||
|
|
@ -57,6 +61,12 @@ function delete_word(theWord) {
|
||||||
} else {
|
} else {
|
||||||
$("#p_" + theWord).remove();
|
$("#p_" + theWord).remove();
|
||||||
}
|
}
|
||||||
|
// remove highlighting for the word
|
||||||
|
let highlightedWords = document.querySelectorAll('.highlighted');
|
||||||
|
for (let x of highlightedWords) {
|
||||||
|
if (x.innerHTML == word)
|
||||||
|
x.replaceWith(x.innerHTML);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -83,7 +93,9 @@ function parseWord(element) {
|
||||||
const word = element
|
const word = element
|
||||||
.querySelector("a.btn.btn-light[role=button]") // 获取当前词频元素的词汇元素
|
.querySelector("a.btn.btn-light[role=button]") // 获取当前词频元素的词汇元素
|
||||||
.innerText // 获取词汇值;
|
.innerText // 获取词汇值;
|
||||||
const freq = Number.parseInt(element.querySelector(`#freq_${word}`).innerText); // 获取词汇的数量
|
let freqId = `freq_${word}`;
|
||||||
|
freqId = CSS.escape(freqId); // for fixing bug 580, escape the apostrophe in the word
|
||||||
|
const freq = Number.parseInt(element.querySelector("#"+freqId).innerText); // 获取词汇的数量
|
||||||
return {
|
return {
|
||||||
word,
|
word,
|
||||||
freq
|
freq
|
||||||
|
|
@ -95,14 +107,14 @@ function parseWord(element) {
|
||||||
*/
|
*/
|
||||||
function wordTemplate(word) {
|
function wordTemplate(word) {
|
||||||
// 这个模板应当与 templates/userpage_get.html 中的 <p id='p_${word.word}' class="new-word" > ... </p> 保持一致
|
// 这个模板应当与 templates/userpage_get.html 中的 <p id='p_${word.word}' class="new-word" > ... </p> 保持一致
|
||||||
return `<p id='p_${word.word}' class="new-word" >
|
return `<p id="p_${word.word}" class="new-word" >
|
||||||
<a id="word_${word.word}" class="btn btn-light" href='http://youdao.com/w/eng/${word.word}/#keyfrom=dict2.index'
|
<a id="word_${word.word}" class="btn btn-light" href='http://youdao.com/w/eng/${word.word}/#keyfrom=dict2.index'
|
||||||
role="button">${word.word}</a>
|
role="button">${word.word}</a>
|
||||||
( <a id="freq_${word.word}" title="${word.word}">${word.freq}</a> )
|
( <a id="freq_${word.word}" title="${word.word}">${word.freq}</a> )
|
||||||
<a class="btn btn-success" onclick="familiar('${word.word}')" role="button">熟悉</a>
|
<a class="btn btn-success" onclick=familiar("${word.word}") role="button">熟悉</a>
|
||||||
<a class="btn btn-warning" onclick="unfamiliar('${word.word}')" role="button">不熟悉</a>
|
<a class="btn btn-warning" onclick=unfamiliar("${word.word}") role="button">不熟悉</a>
|
||||||
<a class="btn btn-danger" onclick="delete_word('${word.word}')" role="button">删除</a>
|
<a class="btn btn-danger" onclick=delete_word("${word.word}") role="button">删除</a>
|
||||||
<a class="btn btn-info" onclick="read_word('${word.word}')" role="button">朗读</a>
|
<a class="btn btn-info" onclick=read_word("${word.word}") role="button">朗读</a>
|
||||||
<a class="btn btn-primary" onclick="addNote('{{ word }}'); saveNote('{{ word }}')" role="button">笔记</a> <!-- Modify to call addNote and then saveNote -->
|
<a class="btn btn-primary" onclick="addNote('{{ word }}'); saveNote('{{ word }}')" role="button">笔记</a> <!-- Modify to call addNote and then saveNote -->
|
||||||
<input type="text" id="note_{{ word }}" class="note-input" placeholder="输入笔记内容" style="display:none;" oninput="saveNote('{{ word }}')"> <!-- Added oninput event -->
|
<input type="text" id="note_{{ word }}" class="note-input" placeholder="输入笔记内容" style="display:none;" oninput="saveNote('{{ word }}')"> <!-- Added oninput event -->
|
||||||
</p>`;
|
</p>`;
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
<p><a href="/login">登录</a> <a href="/signup">注册</a> <a href="/static/usr/instructions.html">使用说明</a></p >
|
<p><a href="/login">登录</a> <a href="/signup">注册</a> <a href="/static/usr/instructions.html">使用说明</a></p >
|
||||||
<p><b> {{ random_ads }}。 <a href="/signup">试试</a>吧!</b></p>
|
<p><b> {{ random_ads }}。 <a href="/signup">试试</a>吧!</b></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="alert alert-success" role="alert">共有文章 <span class="badge bg-success"> {{ number_of_essays }} </span> 篇,覆盖 <span class="badge bg-success"> {{ (ratio * 100) | int }}% </span> 的 Oxford5000 单词</div>
|
<div class="alert alert-success" role="alert">共有文章 <span class="badge bg-success"> {{ number_of_essays }} </span> 篇,Oxford 5000 单词占比 <span class="badge bg-success"> {{ (ratio * 100) | int }}% </span> </div>
|
||||||
<p>粘贴1篇文章 (English only)</p>
|
<p>粘贴1篇文章 (English only)</p>
|
||||||
<form method="post" action="/">
|
<form method="post" action="/">
|
||||||
<textarea name="content" id="article" rows="10" cols="120"></textarea><br/>
|
<textarea name="content" id="article" rows="10" cols="120"></textarea><br/>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=3.0, user-scalable=yes"/>
|
content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=3.0, user-scalable=yes"/>
|
||||||
<link rel="stylesheet" href="static/css/login_service.css">
|
<link rel="stylesheet" href="static/css/login_service.css">
|
||||||
<script src="static/js/jquery.js"></script>
|
<script src="static/js/jquery.js"></script>
|
||||||
|
<script src="static/js/password.js"></script>
|
||||||
<script>
|
<script>
|
||||||
function reset() {
|
function reset() {
|
||||||
let old_password = $("#old-password").val();
|
let old_password = $("#old-password").val();
|
||||||
|
|
@ -24,15 +25,19 @@
|
||||||
alert('密码过于简单。(密码长度至少4位)');
|
alert('密码过于简单。(密码长度至少4位)');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!containsDigitsLettersSpecialCharacters(new_password)) {
|
||||||
|
alert('密码过于简单。(密码要包括数字,字母,特殊符号)');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
$.post("/reset", {'old-password': old_password, 'new-password': new_password},
|
$.post("/reset", {'old-password': old_password, 'new-password': new_password},
|
||||||
function (response) {
|
function (response) {
|
||||||
if (response.status === '1') {
|
console.log(response);
|
||||||
alert('密码修改成功,请重新登录。');
|
if ('success' in response) {
|
||||||
window.location.href = "/login";
|
alert('密码修改成功。');
|
||||||
} else if (response.status === '2') {
|
} else if ('error' in response) {
|
||||||
alert('密码修改失败');
|
alert(`密码修改失败 ${response.error}`);
|
||||||
window.location.href = "/reset";
|
|
||||||
}
|
}
|
||||||
|
window.location.href = `/${response.username}/userpage`;
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE-edge,chrome=1">
|
<meta http-equiv="X-UA-Compatible" content="IE-edge,chrome=1">
|
||||||
<link href="static/css/slide-unlock.css" rel="stylesheet">
|
<link href="static/css/slide-unlock.css" rel="stylesheet">
|
||||||
|
<script src="static/js/password.js"></script>
|
||||||
<script src="static/js/jquery.js"></script>
|
<script src="static/js/jquery.js"></script>
|
||||||
<script src="static/js/jquery.slideunlock.js"></script>
|
<script src="static/js/jquery.slideunlock.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -44,6 +45,10 @@
|
||||||
alert('密码过于简单。(密码长度至少4位)');
|
alert('密码过于简单。(密码长度至少4位)');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!containsDigitsLettersSpecialCharacters(password)) {
|
||||||
|
alert('密码过于简单。(密码要包括数字,字母,特殊符号)');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
is_ok = slider.getIsOk();
|
is_ok = slider.getIsOk();
|
||||||
if(!is_ok){
|
if(!is_ok){
|
||||||
alert('没有滑动验证');
|
alert('没有滑动验证');
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@
|
||||||
|
|
||||||
<div id="text-content">
|
<div id="text-content">
|
||||||
<div id="found">
|
<div id="found">
|
||||||
<div class="alert alert-success" role="alert">According to your word list, your level is <span class="text-decoration-underline" id="user_level">{{ today_article["user_level"] }}</span> and we have chosen an article with a difficulty level of <span class="text-decoration-underline" id="text_level">{{ today_article["text_level"] }}</span> for you. The Oxford word coverage is <span class="text-decoration-underline" id="ratio">{{ (today_article["ratio"] * 100) | int }}%.</span></div>
|
<div class="alert alert-success" role="alert">According to your word list, your level is <span class="text-decoration-underline" id="user_level">{{ today_article["user_level"] }}</span> and we have chosen an article with a difficulty level of <span class="text-decoration-underline" id="text_level">{{ today_article["text_level"] }}</span> for you. <span class="text-decoration-underline" id="ratio">{{ (today_article["ratio"] * 100) | int }}%</span> of the words in this article are in Oxford Word 5000.</div>
|
||||||
<p class="text-muted" id="date">Article added on: {{ today_article["date"] }}</p><br/>
|
<p class="text-muted" id="date">Article added on: {{ today_article["date"] }}</p><br/>
|
||||||
|
|
||||||
<button onclick="saveArticle()" >标记文章</button>
|
<button onclick="saveArticle()" >标记文章</button>
|
||||||
|
|
@ -179,10 +179,10 @@
|
||||||
<a id="word_{{ word }}" class="btn btn-light" href='http://youdao.com/w/eng/{{ word }}/#keyfrom=dict2.index'
|
<a id="word_{{ word }}" class="btn btn-light" href='http://youdao.com/w/eng/{{ word }}/#keyfrom=dict2.index'
|
||||||
role="button">{{ word }}</a>
|
role="button">{{ word }}</a>
|
||||||
( <a id="freq_{{ word }}" title="{{ word }}">{{ freq }}</a> )
|
( <a id="freq_{{ word }}" title="{{ word }}">{{ freq }}</a> )
|
||||||
<a class="btn btn-success" onclick="familiar('{{ word }}')" role="button">熟悉</a>
|
<a class="btn btn-success" onclick=familiar("{{ word }}") role="button">熟悉</a>
|
||||||
<a class="btn btn-warning" onclick="unfamiliar('{{ word }}')" role="button">不熟悉</a>
|
<a class="btn btn-warning" onclick=unfamiliar("{{ word }}") role="button">不熟悉</a>
|
||||||
<a class="btn btn-danger" onclick="delete_word('{{ word }}')" role="button">删除</a>
|
<a class="btn btn-danger" onclick=delete_word("{{ word }}") role="button">删除</a>
|
||||||
<a class="btn btn-info" onclick="read_word('{{ word }}')" role="button">朗读</a>
|
<a class="btn btn-info" onclick=read_word("{{ word }}") role="button">朗读</a>
|
||||||
<a class="btn btn-primary" onclick="addNote('{{ word }}'); saveNote('{{ word }}')" role="button">笔记</a> <!-- Modify to call addNote and then saveNote -->
|
<a class="btn btn-primary" onclick="addNote('{{ word }}'); saveNote('{{ word }}')" role="button">笔记</a> <!-- Modify to call addNote and then saveNote -->
|
||||||
<input type="text" id="note_{{ word }}" class="note-input" placeholder="输入笔记内容" style="display:none;" oninput="saveNote('{{ word }}')"> <!-- Added oninput event -->
|
<input type="text" id="note_{{ word }}" class="note-input" placeholder="输入笔记内容" style="display:none;" oninput="saveNote('{{ word }}')"> <!-- Added oninput event -->
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -178,14 +178,17 @@ def user_mark_word(username):
|
||||||
d = load_freq_history(user_freq_record)
|
d = load_freq_history(user_freq_record)
|
||||||
lst_history = pickle_idea2.dict2lst(d)
|
lst_history = pickle_idea2.dict2lst(d)
|
||||||
lst = []
|
lst = []
|
||||||
|
lst2 = []
|
||||||
for word in request.form.getlist('marked'):
|
for word in request.form.getlist('marked'):
|
||||||
|
if not word in pickle_idea2.exclusion_lst and len(word) > 2:
|
||||||
lst.append((word, [get_time()]))
|
lst.append((word, [get_time()]))
|
||||||
|
lst2.append(word)
|
||||||
d = pickle_idea2.merge_frequency(lst, lst_history)
|
d = pickle_idea2.merge_frequency(lst, lst_history)
|
||||||
if len(lst_history) > 999:
|
if len(lst_history) > 999:
|
||||||
flash('You have way too many words in your difficult-words book. Delete some first.')
|
flash('You have way too many words in your difficult-words book. Delete some first.')
|
||||||
else:
|
else:
|
||||||
pickle_idea2.save_frequency_to_pickle(d, user_freq_record)
|
pickle_idea2.save_frequency_to_pickle(d, user_freq_record)
|
||||||
flash('Added %s.' % (', '.join(request.form.getlist('marked'))))
|
flash('Added %s.' % ', '.join(lst2))
|
||||||
return redirect(url_for('user_bp.userpage', username=username))
|
return redirect(url_for('user_bp.userpage', username=username))
|
||||||
else:
|
else:
|
||||||
return 'Under construction'
|
return 'Under construction'
|
||||||
|
|
|
||||||
|
|
@ -6,3 +6,4 @@ snowballstemmer==2.2.0
|
||||||
Werkzeug==2.2.2
|
Werkzeug==2.2.2
|
||||||
requests
|
requests
|
||||||
pytest~=8.1.1
|
pytest~=8.1.1
|
||||||
|
Flask-HTTPAuth==4.4.0
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue