import json 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('/user_items') @login_required def get_items(): items = [] for item in json.loads(current_user.radicals): if item['image']: items.append({'item_type': 'radical', 'question': item['image'], 'answer': item['meaning']}) else: items.append({'item_type': 'radical', 'question': item['character'], 'answer': item['meaning']}) for item in json.loads(current_user.kanji): made_answer = "" 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('.*', '') items.append({'item_type': 'kanji', 'question': item['character'], 'answer': made_answer, 'answer_meaning': item['meaning']}) for item in json.loads(current_user.vocabulary): items.append({'item_type': 'vocabulary', 'question': item['character'], 'answer': item['kana'], 'answer_meaning': item['meaning']}) return jsonify(item_list=items) @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()