wanikaniburned/wanikaniburned.py

196 lines
6.7 KiB
Python

import json
import random
from flask import Flask, render_template, redirect, url_for, jsonify, flash
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")
@app.route('/quiz_item')
@login_required
def get_quiz():
choices = []
if current_user.radicals:
choices.append('radical')
if current_user.kanji:
choices.append('kanji')
if current_user.vocabulary:
choices.append('vocabulary')
selected_type = random.choice(choices)
if selected_type is 'radical':
selected_item = random.choice(json.loads(current_user.radicals))
if selected_item['image']:
return jsonify(item_type='radical', question=selected_item['image'], answer=selected_item['meaning'])
else:
return jsonify(item_type='radical', question=selected_item['character'], answer=selected_item['meaning'])
elif selected_type is 'kanji':
selected_item = random.choice(json.loads(current_user.kanji))
made_answer = ""
if selected_item['onyomi'] and selected_item['kunyomi']:
made_answer = selected_item['onyomi'] + ',' + selected_item['kunyomi'].replace('.*', '')
elif selected_item['onyomi']:
made_answer = selected_item['onyomi']
elif selected_item['kunyomi']:
made_answer = selected_item['kunyomi'].replace('.*', '')
return jsonify(item_type='kanji', question=selected_item['character'],
answer=made_answer)
else:
selected_item = random.choice(json.loads(current_user.vocabulary))
return jsonify(item_type='vocabulary', question=selected_item['character'], answer=selected_item['kana'])
@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()
app.debug = True
app.run()