diff --git a/README.md b/README.md index 9f4eeb2..6cae148 100644 --- a/README.md +++ b/README.md @@ -3,18 +3,39 @@ ## Requirements - Ubuntu/Debian Linux -- Postgresql +- PostgreSQL - Python 2.7 - Wargaming Developers Account ## Install +For postgres installation + +https://developer.fedoraproject.org/tech/database/postgresql/about.html + + +`````` + ``` pip install -r requirements.txt ``` ### Run +Application + ``` -python app.py +python run_app.py +``` + +Celery Worker + +``` +celery worker -A run_celery.celery -l info +``` + +Celery Beat + +``` + celery beat -A run_celery.celery -l debug ``` diff --git a/alembic/versions/2017_08_27_03_02.py b/alembic/versions/2017_08_27_03_02.py index 97f8a44..28a8f73 100644 --- a/alembic/versions/2017_08_27_03_02.py +++ b/alembic/versions/2017_08_27_03_02.py @@ -1,4 +1,4 @@ -"""empty message +"""New table userwotdetails Revision ID: b3222bf2cedb Revises: 5766fed0b2ef @@ -17,10 +17,30 @@ depends_on = None def upgrade(): - # op.add_column('user', sa.Column('token', sa.String(256), nullable=True, )) + op.create_table( + 'user_wot_details', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('user', sa.Integer(), nullable=True), + sa.Column('nickname', sa.String(32), unique=True), + sa.Column('client_language', sa.String(length=3)), + sa.Column('last_battle_time', sa.Integer), + sa.Column('account_id', sa.Integer), + sa.Column('created_at', sa.Integer), + sa.Column('updated_at', sa.Integer), + sa.Column('logout_at', sa.Integer), + sa.Column('private', sa.String(32)), + sa.Column('global_rating', sa.String(32)), + sa.Column('clan_id', sa.Integer), + sa.PrimaryKeyConstraint('id'), + sa.ForeignKeyConstraint(['user'], ['user.id']), + sa.UniqueConstraint('nickname') + ) pass def downgrade(): - # op.drop_column('user', 'token') + op.drop_table('user_wot_details') pass + +# op.add_column('user', sa.Column('token', sa.String(256), nullable=True, )) +# op.drop_column('user', 'token') diff --git a/app.py b/app.py deleted file mode 100644 index c70c187..0000000 --- a/app.py +++ /dev/null @@ -1,5 +0,0 @@ -from wotstats.init import init_app - -if __name__ == '__main__': - app = init_app() - app.run(host='0.0.0.0', debug=True) diff --git a/wotstats/init.py b/wotstats/init.py index 7e9f514..a6cd872 100644 --- a/wotstats/init.py +++ b/wotstats/init.py @@ -1,27 +1,24 @@ - +import os +# from celery import Celery from flask import Flask, render_template, g, session from wotstats.database import db, migrate from wotstats.openid import oid +from wotstats.pending_tasks import celery from wotstats.views.home import pages_home from wotstats.views.account import pages_account from wotstats.views.wallet import pages_wallet + def init_app(): app = Flask(__name__) - app.debug = True - app.config['SECRET_KEY'] = 'super-secret' - app.config['SQLALCHEMY_DATABASE_URI'] = 'postgres://wot:wot@192.168.1.47/wot' - app.config['OPENID_FS_STORE_PATH'] = 'tmp' - # TODO: rename to WG_APPLICATION_ID - app.config['WG_ID'] = '502910c1c785c3c7ca2e83c9e89bde02' - # app.config['WG_OPENID_URL'] = 'https://eu.wargaming.net/id/openid/' - app.config['WG_OPENID_URL'] = 'https://wargaming.net/id/openid/' - app.config['WG_TOKEN_URL'] = 'https://api.worldoftanks.ru/wot/auth/login/' + app.config.from_pyfile(os.getenv('WOTS_CONFIG', '../config_file.ini')) - # , safe_roots=[] oid.init_app(app) db.init_app(app) migrate.init_app(app, db) + + init_celery(app) + # jwt = JWT(app, authenticate, identity) app.register_blueprint(pages_home) @@ -37,4 +34,18 @@ def init_app(): openid = session['openid'] g.user = User.query.filter_by(openid=openid).first() - return app + return app, celery + + +def init_celery(app): + celery.conf.update(app.config.get_namespace('CELERY_')) + + TaskBase = celery.Task + + class ContextTask(TaskBase): + abstract = True + def __call__(self, *args, **kwargs): + with app.app_context(): + return TaskBase.__call__(self, *args, **kwargs) + celery.Task = ContextTask + from wotstats import tasks diff --git a/wotstats/models/__init__.py b/wotstats/models/__init__.py index ee4c00b..35fc81d 100644 --- a/wotstats/models/__init__.py +++ b/wotstats/models/__init__.py @@ -1 +1,6 @@ + from .user import User +from .userwottokens import UserWotTokens +from .userwotdetails import UserWotDetails +from .userwotstats import UserWotStats +from .userwotdata import UserWotData diff --git a/wotstats/models/user.py b/wotstats/models/user.py index 9ceb0d6..3e429eb 100644 --- a/wotstats/models/user.py +++ b/wotstats/models/user.py @@ -1,14 +1,17 @@ + +from sqlalchemy.dialects.postgresql import ARRAY, HSTORE from wotstats.database import db class User(db.Model): id = db.Column(db.Integer, primary_key=True) - # 0 Inaactive, 1 Active, 2 Blocked + # 0 Inactive, 1 Active, 2 Blocked status = db.Column(db.Integer, default=0, nullable=False) email = db.Column(db.String(256), unique=True, nullable=False) password = db.Column(db.String(32), nullable=False) name = db.Column(db.String(256), unique=True, nullable=False) openid = db.Column(db.String(256), unique=True, nullable=True) + # WoT Token token = db.Column(db.String(256), nullable=True) def __init__(self, email): diff --git a/wotstats/views/account.py b/wotstats/views/account.py index 35bafa7..361e2cf 100644 --- a/wotstats/views/account.py +++ b/wotstats/views/account.py @@ -6,6 +6,7 @@ from flask import ( from jinja2 import TemplateNotFound from wotstats.openid import oid +from wotstats.log import log from wotstats.database import db from wotstats.models import User from wotstats.lib import parse_wargaming_openid_url @@ -13,11 +14,12 @@ from wotstats.lib import parse_wargaming_openid_url pages_account = Blueprint('pages_account', __name__, url_prefix='/account', template_folder='templates') def __get_player_personal_data(): + log.debug(session['openid']) user_id = parse_wargaming_openid_url(session['openid'])[0] - # current_app.config['WG_ID'] + __ = requests.get( 'https://api.worldoftanks.ru/wot/account/info/?application_id={}&account_id={}'.format( - current_app.config['WG_ID'], user_id + current_app.config['WG_APPLICATION_ID'], user_id ) ).json() return __.get('data', {}).get(user_id) @@ -25,6 +27,11 @@ def __get_player_personal_data(): @pages_account.route('/') def index(): + from wotstats.tasks import hello + # from wotstats.tasks import * + + hello.delay() + if not g.user: return redirect(url_for('pages_home.index')) diff --git a/wotstats/views/home.py b/wotstats/views/home.py index 61765e6..fc689f2 100644 --- a/wotstats/views/home.py +++ b/wotstats/views/home.py @@ -8,7 +8,7 @@ from jinja2 import TemplateNotFound from wotstats.openid import oid from wotstats.database import db -from wotstats.models import User +from wotstats.models import * pages_home = Blueprint('pages_home', __name__, template_folder='templates') @@ -81,6 +81,7 @@ def create_profile(): def logout(): session.pop('openid', None) session.pop('token', None) + session.pop('user', None) # flash(u'You were signed out') return redirect(oid.get_next_url()) @@ -90,21 +91,37 @@ def token(): print request.args print request.form - if 'openid' not in session: + if 'openid' not in session or 'user' in session: return redirect(url_for('pages_home.index')) # ImmutableMultiDict([('status', u'ok'), ('access_token', u'a4d0a13df7c733102fbf6cd650794c6d047e91aa'), ('nickname', u'CrazyPants1999'), ('account_id', u'69552613'), ('', u'1505047809')]) if request.args.get('status') == 'ok' and request.args.get('access_token'): + token = UserWotTokens.query.filter_by(user=session['user']) + access_token = request.args.get('access_token') + expires_at = request.args.get('expires_at') + + if token.count() == 0: + t = UserWotTokens() + t.user = session['user'] + t.access_token = access_token + t.expires_at = expires_at + db.session.add(t) + db.session.commit() + else: + token.access_token = access_token + token.expires_at = expires_at + db.session.commit() + session['token'] = { - 'access_token': request.args.get('access_token'), - 'expires_at': request.args.get('expires_at'), + 'access_token': access_token, + 'expires_at': expires_at } return redirect(oid.get_next_url()) - redirect_url = 'http://truesoft.org:5000/token' + # redirect_url = 'http://truesoft.org:5000/token' response = requests.get('{}?application_id={}&nofollow=1&redirect_uri={}'.format( current_app.config['WG_TOKEN_URL'], - current_app.config['WG_ID'], redirect_url)).json() + current_app.config['WG_APPLICATION_ID'], current_app.config['WG_REDIRECT_URL'])).json() if response.get('status') == 'ok': return redirect(response.get('data', {}).get('location')) @@ -115,18 +132,21 @@ def token(): def create_or_login(resp): session['openid'] = resp.identity_url session['token'] = None + session['user'] = None user = User.query.filter_by(openid=resp.identity_url).first() - if user is not None: - # flash(u'Successfully signed in') - g.user = user - if not session['token']: - return redirect(url_for('pages_home.token')) - return redirect(oid.get_next_url()) + if not user: + return redirect(url_for( + 'pages_home.create_profile', + next=oid.get_next_url(), + name=resp.fullname or resp.nickname, + email=resp.email)) - return redirect(url_for( - 'pages_home.create_profile', - next=oid.get_next_url(), - name=resp.fullname or resp.nickname, - email=resp.email)) + session['user'] = user.id + + # flash(u'Successfully signed in') + g.user = user + if not session['token']: + return redirect(url_for('pages_home.token')) + return redirect(oid.get_next_url())