diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/EnglishPal.iml b/.idea/EnglishPal.iml
new file mode 100644
index 0000000..8b8c395
--- /dev/null
+++ b/.idea/EnglishPal.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..7a85af6
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..d90086b
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..86f0b25
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,2 @@
+FROM tiangolo/uwsgi-nginx-flask:python3.6
+COPY ./app /app
diff --git a/Jenkinsfile b/Jenkinsfile
new file mode 100644
index 0000000..434c00f
--- /dev/null
+++ b/Jenkinsfile
@@ -0,0 +1,34 @@
+pipeline {
+ agent any
+
+ stages {
+ stage('MakeDatabasefile') {
+ steps {
+ sh 'touch ./app/static/wordfreqapp.db && rm -f ./app/static/wordfreqapp.db'
+ sh 'cat ./app/static/wordfreqapp.sql | sqlite3 ./app/static/wordfreqapp.db'
+ }
+ }
+ stage('BuildIt') {
+ steps {
+ echo 'Building..'
+ sh 'sudo docker build -t englishpal .'
+ sh 'sudo docker stop $(docker ps -aq)'
+ sh 'sudo docker run -d -p 91:80 -v /var/lib/jenkins/workspace/EnglishPal_Pipeline_master/app/static/frequency:/app/static/frequency -t englishpal'
+ }
+ }
+ stage('TestIt') {
+ steps {
+ echo 'Testing..'
+ sh 'sudo docker run -d -p 4444:4444 selenium/standalone-chrome'
+ sh 'pip3 install pytest -U -q'
+ sh 'pip3 install selenium -U -q'
+ sh 'pytest -v -s --html=EnglishPalTestReport.html ./app/test'
+ }
+ }
+ stage('DeployIt') {
+ steps {
+ echo 'Deploying (TBD)'
+ }
+ }
+ }
+}
diff --git a/app/EverydayArticle.py b/app/EverydayArticle.py
new file mode 100644
index 0000000..9efce8d
--- /dev/null
+++ b/app/EverydayArticle.py
@@ -0,0 +1,114 @@
+#! /usr/bin/python3
+# -*- coding: utf-8 -*-
+
+###########################################################################
+# Copyright 2019 (C) Hui Lan
+# Written permission must be obtained from the author for commercial uses.
+###########################################################################
+
+from UseSqlite import RecordQuery
+import pickle_idea
+import os
+import random
+from flask import Flask, session
+from difficulty import get_difficulty_level, text_difficulty_level, user_difficulty_level
+import SqlWords as sql
+
+app = Flask(__name__)
+app.secret_key = 'lunch.time!'
+
+path_prefix = '/var/www/wordfreq/wordfreq/'
+path_prefix = './' # comment this line in deployment
+
+def load_freq_history(path):
+ d = {}
+ if os.path.exists(path):
+ d = pickle_idea.load_record(path)
+ return d
+
+def within_range(x, y, r):
+ return x > y and abs(x - y) <= r
+
+def Get(user_word_list, articleID):
+
+ rq = RecordQuery(sql.path_prefix + 'static/wordfreqapp.db')
+ if articleID == None:
+ rq.instructions("SELECT * FROM article")
+ else:
+ rq.instructions('SELECT * FROM article WHERE article_id=%d' % (articleID))
+ rq.do()
+ result = rq.get_results()
+
+ # Choose article according to reader's level
+ d1 = load_freq_history(sql.path_prefix + 'static/frequency/frequency.p')
+ d2 = load_freq_history(sql.path_prefix + 'static/words_and_tests.p')
+ d3 = get_difficulty_level(d1, d2)
+
+ 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:
+ for reading in result:
+ text_level = text_difficulty_level(reading['text'], d3)
+ #print('TEXT_LEVEL %4.2f' % (text_level))
+ if within_range(text_level, user_level, 0.5):
+ d = reading
+ break
+
+ 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 += '%s
' % (d['date'])
+ s += '%s
' % (d['text'])
+ s += '%s
' % (d['source'])
+ s += '%s
' % (get_question_part(d['question']))
+ s = s.replace('\n', ' ')
+ s += '%s' % (get_answer_part(d['question']))
+ session['articleID'] = d['article_id']
+ return s
+
+def get_question_part(s):
+ s = s.strip()
+ result = []
+ flag = 0
+ for line in s.split('\n'):
+ line = line.strip()
+ if line == 'QUESTION':
+ result.append(line)
+ flag = 1
+ elif line == 'ANSWER':
+ flag = 0
+ elif flag == 1:
+ result.append(line)
+ return '\n'.join(result)
+
+
+def get_answer_part(s):
+ s = s.strip()
+ result = []
+ flag = 0
+ for line in s.split('\n'):
+ line = line.strip()
+ if line == 'ANSWER':
+ 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
diff --git a/app/SqlWords.py b/app/SqlWords.py
new file mode 100644
index 0000000..1976168
--- /dev/null
+++ b/app/SqlWords.py
@@ -0,0 +1,63 @@
+#! /usr/bin/python3
+# -*- coding: utf-8 -*-
+
+###########################################################################
+# Copyright 2019 (C) Hui Lan
+# Written permission must be obtained from the author for commercial uses.
+###########################################################################
+
+from UseSqlite import InsertQuery, RecordQuery
+from datetime import datetime
+from flask import Flask
+
+app = Flask(__name__)
+app.secret_key = 'lunch.time!'
+
+path_prefix = '/var/www/wordfreq/wordfreq/'
+path_prefix = './' # comment this line in deployment
+
+
+def verify_user(name, password):
+ rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
+ rq.instructions("SELECT * FROM user WHERE name='%s' AND password='%s'" % (name, password))
+ rq.do()
+ result = rq.get_results()
+ return result != []
+
+
+def add_user(name, password):
+ start_date = datetime.now().strftime('%Y%m%d')
+ expiry_date = '20211230'
+ rq = InsertQuery(path_prefix + 'static/wordfreqapp.db')
+ rq.instructions("INSERT INTO user Values ('%s', '%s', '%s', '%s')" % (name, password, start_date, expiry_date))
+ rq.do()
+
+def get_user():
+ rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
+ rq.instructions("SELECT name FROM user")
+ rq.do()
+ result = rq.get_results()
+ return result
+
+def check_username_availability(name):
+ rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
+ rq.instructions("SELECT * FROM user WHERE name='%s'" % (name))
+ rq.do()
+ result = rq.get_results()
+ return result == []
+
+
+def get_expiry_date(name):
+ rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
+ rq.instructions("SELECT expiry_date FROM user WHERE name='%s'" % (name))
+ rq.do()
+ result = rq.get_results()
+ if len(result) > 0:
+ return result[0]['expiry_date']
+ else:
+ return '20191024'
+
+
+
+
+
diff --git a/app/main(1).py b/app/main(1).py
new file mode 100644
index 0000000..518fa48
--- /dev/null
+++ b/app/main(1).py
@@ -0,0 +1,300 @@
+#! /usr/bin/python3
+# -*- coding: utf-8 -*-
+
+###########################################################################
+# Copyright 2019 (C) Hui Lan
+# Written permission must be obtained from the author for commercial uses.
+###########################################################################
+
+from WordFreq import WordFreq
+from wordfreqCMD import youdao_link, sort_in_descending_order
+from UseSqlite import InsertQuery, RecordQuery
+import pickle_idea, pickle_idea2
+import os
+import random, glob
+from datetime import datetime
+from flask import Flask, request, redirect, render_template, url_for, session, abort, flash
+from difficulty import get_difficulty_level, text_difficulty_level, user_difficulty_level
+import EverydayArticle as today
+import SqlWords as sql
+
+app = Flask(__name__)
+app.secret_key = 'lunch.time!'
+
+path_prefix = '/var/www/wordfreq/wordfreq/'
+path_prefix = './' # comment this line in deployment
+
+
+def get_random_image(path):
+ img_path = random.choice(glob.glob(os.path.join(path, '*.jpg')))
+ return img_path[img_path.rfind('/static'):]
+
+
+def get_random_ads():
+ ads = random.choice(['个性化分析精准提升', '你的专有单词本', '智能捕捉阅读弱点,针对性提高你的阅读水平'])
+ return ads
+
+
+def load_freq_history(path):
+ d = {}
+ if os.path.exists(path):
+ d = pickle_idea.load_record(path)
+ return d
+
+
+def appears_in_test(word, d):
+ if not word in d:
+ return ''
+ else:
+ return ','.join(d[word])
+
+
+def get_time():
+ return datetime.now().strftime('%Y%m%d%H%M') # upper to minutes
+
+
+@app.route("//reset", methods=['GET', 'POST'])
+def user_reset(username):
+ if request.method == 'GET':
+ session['articleID'] = None
+ return redirect(url_for('userpage', username=username))
+ else:
+ return 'Under construction'
+
+
+@app.route("/mark", methods=['GET', 'POST'])
+def mark_word():
+ if request.method == 'POST':
+ d = load_freq_history(path_prefix + 'static/frequency/frequency.p')
+ lst_history = pickle_idea.dict2lst(d)
+ lst = []
+ for word in request.form.getlist('marked'):
+ lst.append((word, 1))
+ d = pickle_idea.merge_frequency(lst, lst_history)
+ pickle_idea.save_frequency_to_pickle(d, path_prefix + 'static/frequency/frequency.p')
+ return redirect(url_for('mainpage'))
+ else:
+ return 'Under construction'
+
+
+@app.route("/", methods=['GET', 'POST'])
+def mainpage():
+ if request.method == 'POST': # when we submit a form
+ content = request.form['content']
+ f = WordFreq(content)
+ lst = f.get_freq()
+ page = '\n'
+ # save history
+ d = load_freq_history(path_prefix + 'static/frequency/frequency.p')
+ lst_history = pickle_idea.dict2lst(d)
+ d = pickle_idea.merge_frequency(lst, lst_history)
+ pickle_idea.save_frequency_to_pickle(d, path_prefix + 'static/frequency/frequency.p')
+
+ return page
+ elif request.method == 'GET': # when we load a html page
+ user = ''
+ youdao = {}
+ Eword = {}
+ EwordNum = {}
+ if session.get('logged_in'):
+ user = session['username']
+ random_ads = get_random_ads()
+ d = load_freq_history(path_prefix + 'static/frequency/frequency.p')
+ xi = 1
+ if len(d) > 0:
+ for x in sort_in_descending_order(pickle_idea.dict2lst(d)):
+ if x[1] <= 99:
+ break
+ youdao[xi] = youdao_link(x[0])
+ Eword[xi] = x[0]
+ EwordNum[xi] = x[1]
+ xi = xi + 1
+
+ return render_template('homepage.html', user=user, random_ads=random_ads, youdao=youdao, Eword=Eword,
+ EwordNum=EwordNum, xi=xi)
+
+
+@app.route("//mark", methods=['GET', 'POST'])
+def user_mark_word(username):
+ username = session[username]
+ user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username)
+ if request.method == 'POST':
+ d = load_freq_history(user_freq_record)
+ lst_history = pickle_idea2.dict2lst(d)
+ lst = []
+ for word in request.form.getlist('marked'):
+ lst.append((word, [get_time()]))
+ d = pickle_idea2.merge_frequency(lst, lst_history)
+ pickle_idea2.save_frequency_to_pickle(d, user_freq_record)
+ return redirect(url_for('userpage', username=username))
+ else:
+ return 'Under construction'
+
+
+@app.route("/", methods=['GET', 'POST'])
+def userpage(username):
+ if not session.get('logged_in'):
+ return '请先登录 。
'
+
+ user_expiry_date = session.get('expiry_date')
+ if datetime.now().strftime('%Y%m%d') > user_expiry_date:
+ return '账号 %s 过期。
为了提高服务质量,English Pal 收取会员费用, 每天0元。
请决定你要试用的时间长度,扫描下面支付宝二维码支付。 支付时请注明English Pal Membership Fee 。 我们会于12小时内激活账号。
如果有问题,请加开发者微信 torontohui。
登出
' % (
+ username)
+
+ username = session.get('username')
+
+ user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username)
+
+ if request.method == 'POST': # when we submit a form
+ content = request.form['content']
+ f = WordFreq(content)
+ lst = f.get_freq()
+ page = ' '
+ page += ' '
+ page += '勾选不认识的单词
'
+ page += '\n'
+ return page
+
+ elif request.method == 'GET': # when we load a html page
+ # page = ' \n'
+ # page += ' \n'
+ # page += ' \n' # forbid treating numbers as cell numbers in smart phones
+ # page += 'EnglishPal Study Room for %s ' % (username)
+ # page += 'English Pal for %s 登出
' % (username)
+ # page += '下一篇
' % (username)
+ # page += '阅读文章并回答问题
\n'
+ # page += '%s
' % (today.Get(user_freq_record, session['articleID']))
+ # page += '收集生词吧 (可以在正文中划词,也可以复制黏贴)
'
+ # page += '\n'
+ # page += '''
+ #
+ # '''
+ user = ''
+ youdao = {}
+ word = {}
+ freq = {}
+ fff = {}
+ xi = 1
+ dayartical = today.Get(user_freq_record, session['articleID']);
+ d = load_freq_history(user_freq_record)
+ if len(d) > 0:
+ # page += '我的生词簿
'
+ lst = pickle_idea2.dict2lst(d)
+ lst2 = []
+ for t in lst:
+ lst2.append((t[0], len(t[1])))
+ for x in sort_in_descending_order(lst2):
+ word[xi] = x[0]
+ freq[xi] = x[1]
+ if isinstance(d[word], list): # d[word] is a list of dates
+ fff[xi] = 1
+ #
+ # if freq > 1:
+ # page += ' %s (%d )
\n' % (youdao_link(word), word, '; '.join(d[word]), freq)
+ # else:
+ # page += ' %s (%d )
\n' % (youdao_link(word), word, '; '.join(d[word]), freq)
+ elif isinstance(d[word], int): # d[word] is a frequency. to migrate from old format.
+ # page += '%s %d\n' % (youdao_link(word), word, freq)
+ fff[xi] = 0
+ xi = xi + 1
+
+ return render_template('userpage.html', user=user, dayartical=dayartical, youdao=youdao, word=word, freq=freq,
+ xi=xi, fff=fff)
+
+
+### Sign-up, login, logout ###
+@app.route("/signup", methods=['GET', 'POST'])
+def signup():
+ if request.method == 'GET':
+ return render_template('signup.html')
+ elif request.method == 'POST':
+ username = request.form['username']
+ password = request.form['password']
+
+ available = sql.check_username_availability(username)
+ if not available:
+ flash('用户名 %s 已经被注册。' % (username))
+ return render_template('signup.html')
+ elif len(password.strip()) < 4:
+ return '密码过于简单。'
+ else:
+ sql.add_user(username, password)
+ verified = sql.verify_user(username, password)
+ if verified:
+ session['logged_in'] = True
+ session[username] = username
+ session['username'] = username
+ return '恭喜,你已成功注册, 你的用户名是 %s 。
\
+ 开始使用 返回首页
' % (username, username, username)
+ else:
+ return '用户名密码验证失败。'
+
+
+@app.route("/login", methods=['GET', 'POST'])
+def login():
+ if request.method == 'GET':
+ if not session.get('logged_in'):
+ return render_template('login.html')
+ else:
+ return '你已登录 %s 。 登出点击这里 。' % (
+ session['username'], session['username'])
+ elif request.method == 'POST':
+ # check database and verify user
+ username = request.form['username']
+ password = request.form['password']
+ verified = sql.verify_user(username, password)
+ if verified:
+ session['logged_in'] = True
+ session[username] = username
+ session['username'] = username
+ user_expiry_date = sql.get_expiry_date(username)
+ session['expiry_date'] = user_expiry_date
+ session['articleID'] = None
+ return redirect(url_for('userpage', username=username))
+ else:
+ return '无法通过验证。'
+
+
+@app.route("/logout", methods=['GET', 'POST'])
+def logout():
+ session['logged_in'] = False
+ return redirect(url_for('mainpage'))
+
+
+if __name__ == '__main__':
+ # app.secret_key = os.urandom(16)
+ # app.run(debug=False, port='6000')
+ app.run(debug=True)
+ # app.run(debug=True, port='6000')
+ # app.run(host='0.0.0.0', debug=True, port='6000')
+
diff --git a/app/main.py b/app/main.py
index 1356f12..1c0918d 100644
--- a/app/main.py
+++ b/app/main.py
@@ -15,7 +15,8 @@
from datetime import datetime
from flask import Flask, request, redirect, render_template, url_for, session, abort, flash
from difficulty import get_difficulty_level, text_difficulty_level, user_difficulty_level
-
+import EverydayArticle as today
+import SqlWords as sql
app = Flask(__name__)
app.secret_key = 'lunch.time!'
@@ -28,7 +29,7 @@ def get_random_image(path):
def get_random_ads():
ads = random.choice(['个性化分析精准提升', '你的专有单词本', '智能捕捉阅读弱点,针对性提高你的阅读水平'])
- return ads + '。 试试 吧!'
+ return ads
def load_freq_history(path):
d = {}
@@ -36,83 +37,6 @@ def load_freq_history(path):
d = pickle_idea.load_record(path)
return d
-def verify_user(username, password):
- rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
- rq.instructions("SELECT * FROM user WHERE name='%s' AND password='%s'" % (username, password))
- rq.do()
- result = rq.get_results()
- return result != []
-
-def add_user(username, password):
- start_date = datetime.now().strftime('%Y%m%d')
- expiry_date = '20211230'
- rq = InsertQuery(path_prefix + 'static/wordfreqapp.db')
- rq.instructions("INSERT INTO user Values ('%s', '%s', '%s', '%s')" % (username, password, start_date, expiry_date))
- rq.do()
-
-
-def check_username_availability(username):
- rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
- rq.instructions("SELECT * FROM user WHERE name='%s'" % (username))
- rq.do()
- result = rq.get_results()
- return result == []
-
-def get_expiry_date(username):
- rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
- rq.instructions("SELECT expiry_date FROM user WHERE name='%s'" % (username))
- rq.do()
- result = rq.get_results()
- if len(result) > 0:
- return result[0]['expiry_date']
- else:
- return '20191024'
-
-
-
-def within_range(x, y, r):
- return x > y and abs(x - y) <= r
-
-
-def get_today_article(user_word_list, articleID):
-
- rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
- if articleID == None:
- rq.instructions("SELECT * FROM article")
- else:
- rq.instructions('SELECT * FROM article WHERE article_id=%d' % (articleID))
- rq.do()
- result = rq.get_results()
-
- # Choose article according to reader's level
- d1 = load_freq_history(path_prefix + 'static/frequency/frequency.p')
- d2 = load_freq_history(path_prefix + 'static/words_and_tests.p')
- d3 = get_difficulty_level(d1, d2)
-
- 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:
- for reading in result:
- text_level = text_difficulty_level(reading['text'], d3)
- #print('TEXT_LEVEL %4.2f' % (text_level))
- if within_range(text_level, user_level, 0.5):
- d = reading
- break
-
- 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 += '%s
' % (d['date'])
- s += '%s
' % (d['text'])
- s += '%s
' % (d['source'])
- s += '%s
' % (get_question_part(d['question']))
- s = s.replace('\n', ' ')
- s += '%s' % (get_answer_part(d['question']))
- session['articleID'] = d['article_id']
- return s
-
def appears_in_test(word, d):
if not word in d:
@@ -124,54 +48,6 @@ def appears_in_test(word, d):
def get_time():
return datetime.now().strftime('%Y%m%d%H%M') # upper to minutes
-
-def get_question_part(s):
- s = s.strip()
- result = []
- flag = 0
- for line in s.split('\n'):
- line = line.strip()
- if line == 'QUESTION':
- result.append(line)
- flag = 1
- elif line == 'ANSWER':
- flag = 0
- elif flag == 1:
- result.append(line)
- return '\n'.join(result)
-
-
-def get_answer_part(s):
- s = s.strip()
- result = []
- flag = 0
- for line in s.split('\n'):
- line = line.strip()
- if line == 'ANSWER':
- 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
-
-
-
@app.route("//reset", methods=['GET', 'POST'])
def user_reset(username):
if request.method == 'GET':
@@ -218,40 +94,88 @@ def mainpage():
return page
elif request.method == 'GET': # when we load a html page
- page = '''
-
-
-
-
- EnglishPal 英文单词高效记
-
-
-
- '''
- page += 'English Pal - Learn English in a smart way!
'
+ user = ''
+ youdao = {}
+ Eword = {}
+ EwordNum = {}
if session.get('logged_in'):
- page += ' %s
\n' % (session['username'], session['username'])
- else:
- page += '登录 成为会员 使用说明
\n'
- #page += '
' % (get_random_image(path_prefix + 'static/img/'))
- page += '%s
' % (get_random_ads())
- page += '粘帖1篇文章 (English only)
'
- page += ''
- page += ' '
- page += ' '
- page += ' '
- page += ' '
+ user=session['username']
+ random_ads = get_random_ads()
d = load_freq_history(path_prefix + 'static/frequency/frequency.p')
+ xi = 1
if len(d) > 0:
- page += '最常见的词
'
for x in sort_in_descending_order(pickle_idea.dict2lst(d)):
if x[1] <= 99:
break
- page += '%s %d\n' % (youdao_link(x[0]), x[0], x[1])
+ youdao[xi] = youdao_link(x[0])
+ Eword[xi] = x[0]
+ EwordNum[xi] = x[1]
+ xi=xi+1
+
+ return render_template('homepage.html', user=user,random_ads=random_ads,youdao=youdao,Eword=Eword,EwordNum=EwordNum,xi=xi)
- page += ''
+
+
+
+@app.route("//search", methods=['GET', 'POST'])
+def user_others(username):
+ username = session.get('username')
+ if request.method == 'POST': # when we submit a form
+ page = ' \n'
+ page += ' \n'
+ page += ' \n' # forbid treating numbers as cell numbers in smart phones
+ page += '所查看用户共同的生词 返回
' % (username)
+ Users = request.form.getlist('usernames')
+ nums = len (Users)
+ result = {}
+
+ for uu in Users:
+ x1=path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % uu
+ d1 = load_freq_history(x1)
+ list1 = pickle_idea2.dict2lst(d1)
+ pickle_idea2.lst2dict2(list1, result)
+ if nums == 1:
+ lst = result
+ # print(type(lst))
+ lst2 = []
+ for t in lst:
+ lst2.append((t, lst[t]))
+ for x in sort_in_descending_order(lst2):
+ word = x[0]
+ freq = x[1]
+ page += ' %s (%d )
\n' % (
+ youdao_link(word), word, freq)
+ else:
+ lst = result
+ #print(type(lst))
+ lst2 = []
+ for t in lst:
+ if lst[t] == 1:
+ continue
+ else:
+ lst2.append((t, lst[t]))
+ if lst2 == []:
+ page += 'They don\'t have words they don\'t know\n'
+ else:
+ for x in sort_in_descending_order(lst2):
+ word = x[0]
+ freq = x[1]
+ page += ' %s (%d )
\n' % (youdao_link(word), word, freq)
return page
+ if request.method == 'GET': # when we submit a form
+ lst = sql.get_user()
+ page = ' '
+ page += ' '
+ page += '勾选想要察看的用户 返回
'% (username)
+ page += '\n'% (username)
+ page += ' \n'
+ count = 1
+ for x in lst:
+ page += '%d : %s
\n' % (count, x['name'],x['name'])
+ count += 1
+ page += ' \n'
+ return page
@app.route("//mark", methods=['GET', 'POST'])
def user_mark_word(username):
@@ -269,49 +193,48 @@ def user_mark_word(username):
else:
return 'Under construction'
-
-
@app.route("/", methods=['GET', 'POST'])
def userpage(username):
-
if not session.get('logged_in'):
return '请先登录 。
'
user_expiry_date = session.get('expiry_date')
if datetime.now().strftime('%Y%m%d') > user_expiry_date:
- return '账号 %s 过期。
为了提高服务质量,English Pal 收取会员费用, 每天0元。
请决定你要试用的时间长度,扫描下面支付宝二维码支付。 支付时请注明English Pal Membership Fee 。 我们会于12小时内激活账号。
如果有问题,请加开发者微信 torontohui。
登出
' % (username)
+ return '账号 %s 过期。
为了提高服务质量,English Pal 收取会员费用, 每天0元。
请决定你要试用的时间长度,扫描下面支付宝二维码支付。 支付时请注明English Pal Membership Fee 。 我们会于12小时内激活账号。
如果有问题,请加开发者微信 torontohui。
登出
' % (
+ username)
-
username = session.get('username')
- user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username)
-
+ user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username)
+
if request.method == 'POST': # when we submit a form
content = request.form['content']
f = WordFreq(content)
lst = f.get_freq()
- page = ' '
- page += ' '
+ page = ' '
+ page += ' '
page += '勾选不认识的单词
'
page += '\n' % (username)
- page += ' \n'
+ page += ' \n'
count = 1
- words_tests_dict = pickle_idea.load_record(path_prefix + 'static/words_and_tests.p')
+ words_tests_dict = pickle_idea.load_record(path_prefix + 'static/words_and_tests.p')
for x in lst:
- page += '%d : %s (%d)
\n' % (count, youdao_link(x[0]), appears_in_test(x[0], words_tests_dict), x[0], x[1], x[0])
+ page += '%d : %s (%d)
\n' % (
+ count, youdao_link(x[0]), (x[0], words_tests_dict), x[0], x[1], x[0])
count += 1
page += ' \n'
return page
-
- elif request.method == 'GET': # when we load a html page
+
+ elif request.method == 'GET': # when we load a html page
page = ' \n'
page += ' \n'
- page += ' \n' # forbid treating numbers as cell numbers in smart phones
+ page += ' \n' # forbid treating numbers as cell numbers in smart phones
page += 'EnglishPal Study Room for %s ' % (username)
page += 'English Pal for %s 登出
' % (username)
+ page += '查看其他人的共同生词
'% (username)
page += '下一篇
' % (username)
page += '阅读文章并回答问题
\n'
- page += '%s
' % (get_today_article(user_freq_record, session['articleID']))
+ page += '%s
' % (today.Get(user_freq_record, session['articleID']))
page += '收集生词吧 (可以在正文中划词,也可以复制黏贴)
'
page += '' % (username)
page += ' '
@@ -332,7 +255,7 @@ def userpage(username):
document.getElementById("text-content").addEventListener("touchstart", fillinWord, false);
'''
-
+
d = load_freq_history(user_freq_record)
if len(d) > 0:
page += '我的生词簿
'
@@ -343,15 +266,16 @@ def userpage(username):
for x in sort_in_descending_order(lst2):
word = x[0]
freq = x[1]
- if isinstance(d[word], list): # d[word] is a list of dates
+ if isinstance(d[word], list): # d[word] is a list of dates
if freq > 1:
- page += ' %s (%d )
\n' % (youdao_link(word), word, '; '.join(d[word]), freq)
+ page += ' %s (%d )
\n' % (
+ youdao_link(word), word, freq)
else:
- page += ' %s (%d )
\n' % (youdao_link(word), word, '; '.join(d[word]), freq)
- elif isinstance(d[word], int): # d[word] is a frequency. to migrate from old format.
- page += '%s %d\n' % (youdao_link(word), word, freq)
-
-
+ page += ' %s (%d )
\n' % (
+ youdao_link(word), word, freq)
+ elif isinstance(d[word], int): # d[word] is a frequency. to migrate from old format.
+ page += '%s %d\n' % (youdao_link(word), word, freq)
+
return page
### Sign-up, login, logout ###
@@ -363,15 +287,15 @@ def signup():
username = request.form['username']
password = request.form['password']
- available = check_username_availability(username)
+ available = sql.check_username_availability(username)
if not available:
flash('用户名 %s 已经被注册。' % (username))
return render_template('signup.html')
elif len(password.strip()) < 4:
return '密码过于简单。'
else:
- add_user(username, password)
- verified = verify_user(username, password)
+ sql.add_user(username, password)
+ verified = sql.verify_user(username, password)
if verified:
session['logged_in'] = True
session[username] = username
@@ -393,12 +317,12 @@ def login():
# check database and verify user
username = request.form['username']
password = request.form['password']
- verified = verify_user(username, password)
+ verified = sql.verify_user(username, password)
if verified:
session['logged_in'] = True
session[username] = username
session['username'] = username
- user_expiry_date = get_expiry_date(username)
+ user_expiry_date = sql.get_expiry_date(username)
session['expiry_date'] = user_expiry_date
session['articleID'] = None
return redirect(url_for('userpage', username=username))
diff --git a/app/pickle_idea2.py b/app/pickle_idea2.py
index 91a5b11..f2e75fb 100644
--- a/app/pickle_idea2.py
+++ b/app/pickle_idea2.py
@@ -25,6 +25,14 @@ def lst2dict(lst, d):
else:
d[word] += dates
+def lst2dict2(lst1, d):
+ for x in lst1:
+ word = x[0]
+ dates = 1
+ if not word in d:
+ d[word] = dates
+ else:
+ d[word] += dates
def dict2lst(d):
if len(d) > 0:
diff --git a/app/templates/homepage.html b/app/templates/homepage.html
new file mode 100644
index 0000000..ebbd7d8
--- /dev/null
+++ b/app/templates/homepage.html
@@ -0,0 +1,27 @@
+
+
+
+
+
+ 王天豪EnglishPal 英文单词高效记
+
+
+ English Pal - Learn English in a smart way!
+ {% if username %}
+ user
+ {% else %}
+ 登录 成为会员 使用说明
+ {% endif %}
+ {{random_ads}}。 试试 吧!
+ 粘帖1篇文章 (English only)
+
+
+
+
+
+ 最常见的词
+ {% for i in range(xi) %}
+ {{Eword[i]}} {{EwordNum[i]}}
+ {% endfor %}
+
+
diff --git a/app/templates/userpage.html b/app/templates/userpage.html
new file mode 100644
index 0000000..57844b7
--- /dev/null
+++ b/app/templates/userpage.html
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+ EnglishPal Study Room for {{user}}
+
+
+
+
+
+ English Pal for {{user}} 登出
+ 下一篇
+ 阅读文章并回答问题
+ {{dayartical}}
+ 收集生词吧 (可以在正文中划词,也可以复制黏贴)
+
+
+
+
+
+ 我的生词簿
+ {% for i in range(xi) %}
+ {% if fff[i] %}
+ {% if freq>1 %}
+ {{word[i]}} ; ({{freq[i]}} )
+ {% else %}
+ {{word[i]}} ; ({{freq[i]}} )
+ {% endif %}
+ {% else %}
+ {{word[i]}} {{freq[i]}}
+ fff[xi] = 0
+ {% endif %}
+ {{word[i]}} {{freq[i]}}
+ {% endfor %}
+
+
\ No newline at end of file
diff --git a/app/test.py b/app/test.py
new file mode 100644
index 0000000..ef9ecbd
--- /dev/null
+++ b/app/test.py
@@ -0,0 +1,83 @@
+#! /usr/bin/python3
+# -*- coding: utf-8 -*-
+
+###########################################################################
+# Copyright 2019 (C) Hui Lan
+# Written permission must be obtained from the author for commercial uses.
+###########################################################################
+
+from WordFreq import WordFreq
+from wordfreqCMD import youdao_link, sort_in_descending_order
+from UseSqlite import InsertQuery, RecordQuery
+import pickle_idea, pickle_idea2
+import os
+import random, glob
+from datetime import datetime
+from flask import Flask, request, redirect, render_template, url_for, session, abort, flash
+from difficulty import get_difficulty_level, text_difficulty_level, user_difficulty_level
+import EverydayArticle as today
+import SqlWords as sql
+app = Flask(__name__)
+app.secret_key = 'lunch.time!'
+def load_freq_history(path):
+ d = {}
+ if os.path.exists(path):
+ d = pickle_idea.load_record(path)
+ return d
+
+path_prefix = '/var/www/wordfreq/wordfreq/'
+path_prefix = './' # comment this line in deployment
+result={}
+d={}
+lst = sql.get_user()
+x1=path_prefix + 'static/frequency/' + 'frequency_lanhui.pickle'
+x2=path_prefix + 'static/frequency/' + 'frequency_lanhui.pickle'
+d1 = load_freq_history(x1)
+d2 = load_freq_history(x2)
+lst1 = pickle_idea2.dict2lst(d1)
+lst2 = pickle_idea2.dict2lst(d2)
+pickle_idea2.lst2dict2(lst1,d)
+print(d)
+for xxx in d:
+ print(xxx)
+ print(d[xxx])
+ print(type(d[xxx]))
+# for x in lst1:
+# word = x[0]
+# dates = x[1]
+# if word in d:
+# print("1111")
+# d[word] += dates
+# else:
+# print("2222")
+# d[word] = dates
+#
+# for x in lst2:
+# word = x[0]
+# dates = x[1]
+# if word in d:
+# print("1111")
+# d[word] += dates
+# else:
+# print("2222")
+# d[word] = dates
+# m=lst1[0]
+# print(m)
+# www = m[0]
+# print(www)
+# if www in lst2:
+# print("1111")
+# for x in lst1:
+# word = x[0]
+# dates = x[1]
+# if word in lst2:
+# print(word)
+# if not word in d:
+# d[word] = dates
+# else:
+# d[word] += dates
+
+#
+# print(d1)
+# for xx in lst_history:
+# print(xx)
\ No newline at end of file
diff --git "a/\346\274\224\347\244\272\350\247\206\351\242\221" "b/\346\274\224\347\244\272\350\247\206\351\242\221"
new file mode 100644
index 0000000..f3db691
--- /dev/null
+++ "b/\346\274\224\347\244\272\350\247\206\351\242\221"
@@ -0,0 +1,2 @@
+软件项目管理(新功能演示):https://www.bilibili.com/video/BV1wy4y1M7h6/
+软件架构(EnglishPal重构):https://www.bilibili.com/video/BV13y4y1M7Xo/