diff options
author | Hui Lan <lanhui@zjnu.edu.cn> | 2019-11-01 20:51:19 +0800 |
---|---|---|
committer | Hui Lan <lanhui@zjnu.edu.cn> | 2019-11-01 20:51:19 +0800 |
commit | a8f6a99bb3d3dba85705ed7df93145c28168d659 (patch) | |
tree | b21a324eb857b0b236ea76f22692e18420258e45 /app/wordfreqWEB.py |
englishpal: first commit
Diffstat (limited to 'app/wordfreqWEB.py')
-rw-r--r-- | app/wordfreqWEB.py | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/app/wordfreqWEB.py b/app/wordfreqWEB.py new file mode 100644 index 0000000..7d34ad0 --- /dev/null +++ b/app/wordfreqWEB.py @@ -0,0 +1,337 @@ +#! /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
+
+
+app = Flask(__name__)
+
+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 + '。 <a href="/signup">试试</a>吧!'
+
+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 get_today_article():
+ rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
+ rq.instructions("SELECT * FROM article")
+ rq.do()
+ result = rq.get_results()
+ d = random.choice(result)
+ s = '<p><b>%s</b></p>' % (d['date'])
+ s += '<p>%s</p>' % (d['text'])
+ s += '<p><i>%s</i></p>' % (d['source'])
+ s += '<p>%s</p>' % (get_question_part(d['question']))
+ s = s.replace('\n', '<br/>')
+ 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 = '''
+<script type="text/javascript">
+
+ function toggle_visibility(id) {
+ var e = document.getElementById(id);
+ if(e.style.display == 'block')
+ e.style.display = 'none';
+ else
+ e.style.display = 'block';
+ }
+</script>
+ '''
+ html_code = js
+ html_code += '\n'
+ html_code += '<button onclick="toggle_visibility(\'answer\');">Click to show answer</button>\n'
+ html_code += '<div id="answer" style="display:none;">%s</div>\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 = '<form method="post" action="/mark">\n'
+ count = 1
+ for x in lst:
+ page += '<p><font color="grey">%d</font>: <a href="%s">%s</a> (%d) <input type="checkbox" name="marked" value="%s"></p>\n' % (count, youdao_link(x[0]), x[0], x[1], x[0])
+ count += 1
+ page += ' <input type="submit" value="确定并返回"/>\n'
+ page += '</form>\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 = '<p><b><font color="red">English Pal - Learn English in a smart way!</font></b>'
+ if session.get('logged_in'):
+ page += ' <a href="%s">%s</a></p>\n' % (session['username'], session['username'])
+ else:
+ page += ' <a href="/login">登录</a> <a href="/signup">成为会员</a> <a href="/static/usr/instructions.html">使用说明</a> </p>\n'
+ #page += '<p><img src="%s" width="400px" alt="advertisement"/></p>' % (get_random_image(path_prefix + 'static/img/'))
+ page += '<p><b>%s</b></p>' % (get_random_ads())
+ page += '<p>粘帖1篇文章 (English only)</p>'
+ page += '<form method="post" action="/">'
+ page += ' <textarea name="content" rows="10" cols="80"></textarea><br/>'
+ page += ' <input type="submit" value="get文章中的词频"/>'
+ page += ' <input type="reset" value="清除"/>'
+ page += '</form>'
+ d = load_freq_history(path_prefix + 'static/frequency/frequency.p')
+ if len(d) > 0:
+ page += '<p><b>最常见的词</b></p>'
+ for x in sort_in_descending_order(pickle_idea.dict2lst(d)):
+ if x[1] <= 99:
+ break
+ page += '<a href="%s">%s</a> %d\n' % (youdao_link(x[0]), x[0], x[1])
+
+ return page
+
+
+@app.route("/<username>/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("/<username>", methods=['GET', 'POST'])
+def userpage(username):
+
+ if not session.get('logged_in'):
+ return '<p>请先<a href="/login">登录</a>。</p>'
+
+ user_expiry_date = session.get('expiry_date')
+ if datetime.now().strftime('%Y%m%d') > user_expiry_date:
+ return '<p>账号 %s 过期。</p><p>为了提高服务质量,English Pal 收取会员费用, 每天1元。 请决定你要试用的时间长度,扫描下面支付宝二维码支付。 支付时请注明<i>English Pal Membership Fee</i>。 我们会于12小时内激活账号。</p><p><img src="static/donate-the-author.jpg" width="120px" alt="支付宝二维码" /></p><p>如果有问题,请加开发者微信 torontohui</p>' % (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 = '<p>勾选不认识的单词</p>'
+ page += '<form method="post" action="/%s/mark">\n' % (username)
+ count = 1
+ words_tests_dict = pickle_idea.load_record(path_prefix + 'static/words_and_tests.p')
+ for x in lst:
+ page += '<p><font color="grey">%d</font>: <a href="%s" title="%s">%s</a> (%d) <input type="checkbox" name="marked" value="%s"></p>\n' % (count, youdao_link(x[0]), appears_in_test(x[0], words_tests_dict), x[0], x[1], x[0])
+ count += 1
+ page += ' <input type="submit" value="加入我的生词簿"/>\n'
+ page += '</form>\n'
+ return page
+
+ elif request.method == 'GET': # when we load a html page
+ page = '<meta charset="UTF8">'
+ page += '<p><b>English Pal for <font color="red">%s</font></b> <a href="/logout">登出</a></p>' % (username)
+ page += '<p><b>阅读文章并回答问题</b></p>\n'
+ page += '%s' % (get_today_article())
+ page += '<p>收集生词吧</p>'
+ page += '<form method="post" action="/%s">' % (username)
+ page += ' <textarea name="content" rows="10" cols="80"></textarea><br/>'
+ page += ' <input type="submit" value="get 所有词的频率"/>'
+ page += ' <input type="reset" value="清除"/>'
+ page += '</form>\n'
+ d = load_freq_history(user_freq_record)
+ if len(d) > 0:
+ page += '<p><b>我的生词簿</b></p>'
+ 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 += '<a href="%s">%s</a> (<a title="%s">%d</a>)\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 += '<a href="%s">%s</a>%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 '<p>恭喜,你已成功注册, 你的用户名是 <a href="%s">%s</a>。 请记下用户名与密码。</p><p>为了提高服务质量,我们收取会员费,每天1元。 头100名用户享8折优惠。 请决定使用时间长度后,请扫描下面支付宝二维码支付。 未及时成为会员的账号,12小时后停用。如果有问题,请加开发者微信 torontohui。</p> \
+ <p><img src="static/donate-the-author.jpg" width="120px" alt="支付宝二维码" /></p> \
+ <p><a href="/%s">开始使用</a> <a href="/">返回首页</a><p/>' % (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 '你已登录 <a href="/%s">%s</a>。 登出点击<a href="/logout">这里</a>。' % (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(port='6000')
+
|