From a8f6a99bb3d3dba85705ed7df93145c28168d659 Mon Sep 17 00:00:00 2001
From: Hui Lan
Date: Fri, 1 Nov 2019 20:51:19 +0800
Subject: englishpal: first commit
---
app/main.py | 369 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 369 insertions(+)
create mode 100644 app/main.py
(limited to 'app/main.py')
diff --git a/app/main.py b/app/main.py
new file mode 100644
index 0000000..c3fb28b
--- /dev/null
+++ b/app/main.py
@@ -0,0 +1,369 @@
+#! /usr/bin/python3
+# -*- coding: utf-8 -*-
+
+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
+
+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 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 = start_date
+ 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 abs(x - y)/y <= r
+
+
+def get_today_article(user_word_list):
+
+ rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
+ rq.instructions("SELECT * FROM article")
+ 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 = {}
+ no_match = 0
+ 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
+ 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.25):
+ d = reading
+ break
+
+ if len(d) == 0:
+ no_match = 1
+ d = random.choice(result)
+ text_level = text_difficulty_level(d['text'], d3)
+
+ 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']))
+ return s
+
+
+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
+
+
+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 += '\n'
+ html_code += '%s
\n' % ('\n'.join(result))
+ return html_code
+
+
+@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
+ page = 'English Pal - Learn English in a smart way!'
+ 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 += ''
+ d = load_freq_history(path_prefix + 'static/frequency/frequency.p')
+ 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])
+
+ return page
+
+
+@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 收取会员费用, 每天1元。 请决定你要试用的时间长度,扫描下面支付宝二维码支付。 支付时请注明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 += '\n'
+ return page
+
+ elif request.method == 'GET': # when we load a html page
+ page = ''
+ page += 'English Pal for %s 登出
' % (username)
+ page += '阅读文章并回答问题
\n'
+ page += '%s' % (get_today_article(user_freq_record))
+ page += '收集生词吧
'
+ page += '\n'
+ 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 = x[0]
+ freq = x[1]
+ if isinstance(d[word], list): # d[word] is a list of dates
+ 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)
+
+
+ return page
+
+### 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 = 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)
+ if verified:
+ session['logged_in'] = True
+ session[username] = username
+ session['username'] = username
+ return '恭喜,你已成功注册, 你的用户名是 %s。 请记下用户名与密码。
为了提高服务质量,我们收取会员费,每天1元。 头100名用户享8折优惠。 请决定使用时间长度后,请扫描下面支付宝二维码支付。 未及时成为会员的账号,12小时后停用。如果有问题,请加开发者微信 torontohui。
\
+ 
\
+ 开始使用 返回首页
' % (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 = verify_user(username, password)
+ if verified:
+ session['logged_in'] = True
+ session[username] = username
+ session['username'] = username
+ user_expiry_date = get_expiry_date(username)
+ session['expiry_date'] = user_expiry_date
+ 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')
+
--
cgit v1.2.1