2015-10-04 02:41:16 +01:00
|
|
|
import json
|
2015-10-05 12:29:31 +01:00
|
|
|
from flask import Flask, render_template, redirect, url_for, jsonify, flash
|
2015-10-04 02:41:16 +01:00
|
|
|
from flask.ext.login import LoginManager, login_user, login_required, current_user, logout_user, login_fresh
|
|
|
|
from flask.ext.sqlalchemy import SQLAlchemy
|
|
|
|
from flask.ext.wtf import Form
|
|
|
|
import requests
|
|
|
|
from wtforms import StringField
|
|
|
|
from wtforms.validators import DataRequired
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
app.config.from_pyfile('config.py')
|
|
|
|
login_manager = LoginManager()
|
|
|
|
login_manager.init_app(app)
|
|
|
|
db = SQLAlchemy(app)
|
|
|
|
|
|
|
|
|
|
|
|
class LoginForm(Form):
|
|
|
|
api_key = StringField('api_key', validators=[DataRequired()])
|
|
|
|
|
|
|
|
|
|
|
|
class User(db.Model):
|
|
|
|
__tablename__ = 'users'
|
|
|
|
api_key = db.Column(db.String, unique=True, primary_key=True)
|
|
|
|
radicals = db.Column(db.String)
|
|
|
|
kanji = db.Column(db.String)
|
|
|
|
vocabulary = db.Column(db.String)
|
|
|
|
username = db.Column(db.String)
|
|
|
|
gravatar = db.Column(db.String)
|
|
|
|
last_updated = db.Column(db.DateTime)
|
|
|
|
|
|
|
|
def __init__(self, api_key):
|
|
|
|
self.api_key = api_key
|
|
|
|
self.last_updated = datetime.utcnow()
|
|
|
|
self.parse_radicals_and_userdata()
|
|
|
|
self.parse_kanji()
|
|
|
|
self.parse_vocabulary()
|
|
|
|
db.session.add(self)
|
|
|
|
db.session.commit()
|
|
|
|
|
|
|
|
def is_authenticated(self):
|
|
|
|
return True
|
|
|
|
|
|
|
|
def is_active(self):
|
|
|
|
return True
|
|
|
|
|
|
|
|
def is_anonymous(self):
|
|
|
|
return False
|
|
|
|
|
|
|
|
def get_id(self):
|
|
|
|
return str(self.api_key)
|
|
|
|
|
|
|
|
def parse_radicals_and_userdata(self):
|
|
|
|
response = requests.get("https://www.wanikani.com/api/user/" + self.api_key + "/radicals/")
|
|
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
|
|
|
if data.get('error'):
|
|
|
|
raise ValueError(data['error']['message'])
|
|
|
|
items = []
|
|
|
|
self.username = data['user_information']['username']
|
|
|
|
self.gravatar = data['user_information']['gravatar']
|
|
|
|
if data.get('requested_information'):
|
|
|
|
for item in data['requested_information']:
|
|
|
|
if item.get('user_specific') and item['user_specific']['burned']:
|
|
|
|
items.append({'character': item['character'], 'meaning': item['meaning'], 'image': item['image']})
|
|
|
|
self.radicals = json.dumps(items)
|
|
|
|
|
|
|
|
def parse_kanji(self):
|
|
|
|
response = requests.get("https://www.wanikani.com/api/user/" + self.api_key + "/kanji/")
|
|
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
|
|
|
if data.get('error'):
|
|
|
|
raise ValueError(data['error']['message'])
|
|
|
|
items = []
|
|
|
|
if data.get('requested_information'):
|
|
|
|
for item in data['requested_information']:
|
|
|
|
if item.get('user_specific') and item['user_specific']['burned']:
|
|
|
|
items.append({'character': item['character'], 'meaning': item['meaning'], 'onyomi': item['onyomi'],
|
|
|
|
'kunyomi': item['kunyomi']})
|
|
|
|
self.kanji = json.dumps(items)
|
|
|
|
|
|
|
|
def parse_vocabulary(self):
|
|
|
|
response = requests.get("https://www.wanikani.com/api/user/" + self.api_key + "/vocabulary/")
|
|
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
|
|
|
if data.get('error'):
|
|
|
|
raise ValueError(data['error']['message'])
|
|
|
|
items = []
|
|
|
|
if data.get('requested_information'):
|
|
|
|
for item in data['requested_information']['general']:
|
|
|
|
if item.get('user_specific') and item['user_specific']['burned']:
|
|
|
|
items.append({'character': item['character'], 'meaning': item['meaning'], 'kana': item['kana']})
|
|
|
|
self.vocabulary = json.dumps(items)
|
|
|
|
|
|
|
|
def update_all(self):
|
|
|
|
self.parse_radicals_and_userdata()
|
|
|
|
self.parse_kanji()
|
|
|
|
self.parse_vocabulary()
|
|
|
|
self.last_updated = datetime.utcnow()
|
|
|
|
db.session.add(self)
|
|
|
|
db.session.commit()
|
|
|
|
|
|
|
|
|
|
|
|
@login_manager.user_loader
|
|
|
|
def load_user(api_key):
|
|
|
|
return User.query.get(str(api_key))
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/', methods=('GET', 'POST'))
|
|
|
|
def show_home():
|
|
|
|
if current_user.is_authenticated:
|
|
|
|
return redirect(url_for('show_quiz'))
|
|
|
|
form = LoginForm()
|
|
|
|
if form.validate_on_submit():
|
|
|
|
user = User.query.get(str(form.api_key.data))
|
|
|
|
if user:
|
|
|
|
login_user(user)
|
|
|
|
return redirect(url_for('show_quiz'))
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
new_user = User(str(form.api_key.data))
|
|
|
|
login_user(new_user)
|
|
|
|
return redirect(url_for('show_quiz'))
|
|
|
|
except ValueError as err:
|
|
|
|
flash(err)
|
|
|
|
return render_template("welcome.html", form=form)
|
|
|
|
return render_template("welcome.html", form=form)
|
|
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
@app.route('/quiz')
|
|
|
|
def show_quiz():
|
|
|
|
if not login_fresh():
|
|
|
|
if User.query.get(current_user.api_key):
|
|
|
|
return render_template("quiz.html")
|
|
|
|
else:
|
|
|
|
logout_user()
|
|
|
|
return redirect(url_for('show_home'))
|
|
|
|
return render_template("quiz.html")
|
|
|
|
|
|
|
|
|
2015-10-05 12:25:11 +01:00
|
|
|
@app.route('/user_items')
|
2015-10-04 02:41:16 +01:00
|
|
|
@login_required
|
2015-10-05 12:25:11 +01:00
|
|
|
def get_items():
|
|
|
|
items = []
|
2015-10-05 16:06:10 +01:00
|
|
|
radical_count = 0
|
2015-10-05 12:25:11 +01:00
|
|
|
for item in json.loads(current_user.radicals):
|
2015-10-05 16:06:10 +01:00
|
|
|
radical_count += 1
|
2015-10-05 12:25:11 +01:00
|
|
|
if item['image']:
|
|
|
|
items.append({'item_type': 'radical', 'question': item['image'], 'answer': item['meaning']})
|
2015-10-04 02:41:16 +01:00
|
|
|
else:
|
2015-10-05 12:25:11 +01:00
|
|
|
items.append({'item_type': 'radical', 'question': item['character'], 'answer': item['meaning']})
|
2015-10-05 16:06:10 +01:00
|
|
|
kanji_count = 0
|
2015-10-05 12:25:11 +01:00
|
|
|
for item in json.loads(current_user.kanji):
|
2015-10-05 16:06:10 +01:00
|
|
|
kanji_count += 1
|
2015-10-04 02:41:16 +01:00
|
|
|
made_answer = ""
|
2015-10-05 12:25:11 +01:00
|
|
|
if item['onyomi'] and item['kunyomi']:
|
|
|
|
made_answer = item['onyomi'] + ',' + item['kunyomi'].replace('.*', '')
|
|
|
|
elif item['onyomi']:
|
|
|
|
made_answer = item['onyomi']
|
|
|
|
elif item['kunyomi']:
|
|
|
|
made_answer = item['kunyomi'].replace('.*', '')
|
2015-10-05 12:41:55 +01:00
|
|
|
items.append({'item_type': 'kanji', 'question': item['character'], 'answer': made_answer,
|
|
|
|
'answer_meaning': item['meaning']})
|
2015-10-05 16:06:10 +01:00
|
|
|
vocabulary_count = 0
|
2015-10-05 12:25:11 +01:00
|
|
|
for item in json.loads(current_user.vocabulary):
|
2015-10-05 16:06:10 +01:00
|
|
|
vocabulary_count += 1
|
2015-10-05 12:41:55 +01:00
|
|
|
items.append({'item_type': 'vocabulary', 'question': item['character'], 'answer': item['kana'],
|
|
|
|
'answer_meaning': item['meaning']})
|
2015-10-05 16:06:10 +01:00
|
|
|
return jsonify(radical_count=radical_count, kanji_count=kanji_count, vocabulary_count=vocabulary_count,
|
|
|
|
item_list=items)
|
2015-10-04 02:41:16 +01:00
|
|
|
|
|
|
|
|
|
|
|
@app.route('/refresh', methods=['POST'])
|
|
|
|
def refresh_api():
|
|
|
|
current_user.update_all()
|
|
|
|
return "202"
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/logout')
|
|
|
|
def logout():
|
|
|
|
logout_user()
|
|
|
|
return redirect(url_for('show_home'))
|
|
|
|
|
|
|
|
|
|
|
|
@login_manager.unauthorized_handler
|
|
|
|
def unauthorized():
|
|
|
|
return redirect(url_for('show_home'))
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
db.create_all()
|
2015-10-05 16:06:10 +01:00
|
|
|
app.run(threaded=True)
|