Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add manual AGA syncing #174

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
POSTGRES_DB=league
POSTGRES_USER=league
POSTGRES_PASSWORD=league
CELERY_BROKER_URL=redis://cache:6379/0
6 changes: 5 additions & 1 deletion app/autoapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@

CONFIG = DevConfig if get_debug_flag() else ProdConfig

app = create_app(CONFIG)
flaskapp = create_app(CONFIG)

# push app context so we can reference extensions
flaskapp.app_context().push()
celery = flaskapp.extensions['flask-celeryext'].celery
7 changes: 7 additions & 0 deletions app/league/admin/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ def settings():
return render_template('admin/settings.html')


@blueprint.route('/aga-syncing')
@admin_required
def aga_syncing():
"""AGA syncing."""
return render_template('admin/aga_syncing.html')


@blueprint.route('/site_settings/', methods=['GET', 'POST'])
@admin_required
def manage_site_settings():
Expand Down
27 changes: 24 additions & 3 deletions app/league/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from flask import Blueprint, jsonify, request, url_for
from flask_login import login_required

from league import tasks
from league.api.forms import GameCreateForm, GameUpdateForm
from league.extensions import csrf_protect, messenger
from league.models import Color, Game, Player
Expand All @@ -20,7 +21,8 @@ def _set_game_create_choices(game_create_form):
Should allow up to one more than current maxima.
"""
max_season, max_episode = Game.get_max_season_ep()
game_create_form.season.choices = [(s, s) for s in range(1, max_season + 2)]
game_create_form.season.choices = [(s, s) for s in
range(1, max_season + 2)]
game_create_form.episode.choices = [(e, e) for e in
range(1, max_episode + 2)]

Expand Down Expand Up @@ -86,10 +88,12 @@ def _slack_game_msg(game):

return result.format(w_name=game.white.full_name,
w_url=url_for('dashboard.get_player',
player_id=game.white.id, _external=True),
player_id=game.white.id,
_external=True),
b_name=game.black.full_name,
b_url=url_for('dashboard.get_player',
player_id=game.black.id, _external=True),
player_id=game.black.id,
_external=True),
handicap=game.handicap,
komi=game.komi,
date_string=game.played_at,
Expand Down Expand Up @@ -137,3 +141,20 @@ def delete_game(game_id):
return '', 204
else:
return '', 404


@blueprint.route('/hello-world')
def hello_world():
"""Run and wait for Hello world task."""
result = tasks.hello_world.delay()

return result.wait(), 200


@blueprint.route('/queue-aga-sync', methods=['POST'])
@login_required
def queue_aga_sync():
"""Queue AGA sync job."""
tasks.sync_aga_data.delay()

return 'Task queued!', 200
7 changes: 4 additions & 3 deletions app/league/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@

from league import admin, api, commands, dashboard, public
from league.assets import assets
from league.extensions import (bcrypt, cache, csrf_protect, db, debug_toolbar,
login_manager, messenger, migrate)
from league.extensions import (bcrypt, cache, celery, csrf_protect, db,
debug_toolbar, login_manager, messenger, migrate)
from league.public.forms import LoginForm
from league.settings import ProdConfig


def create_app(config_object=ProdConfig):
"""
An application factory.
Create application using app factory.

See: http://flask.pocoo.org/docs/patterns/appfactories/.

Expand All @@ -38,6 +38,7 @@ def register_extensions(app):
bcrypt.init_app(app)
cache.init_app(app)
db.init_app(app)
celery.init_app(app)
csrf_protect.init_app(app)
login_manager.init_app(app)
debug_toolbar.init_app(app)
Expand Down
2 changes: 2 additions & 0 deletions app/league/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"""
from flask_bcrypt import Bcrypt
from flask_caching import Cache
from flask_celeryext import FlaskCeleryExt
from flask_debugtoolbar import DebugToolbarExtension
from flask_login import LoginManager
from flask_migrate import Migrate
Expand All @@ -15,6 +16,7 @@
from league.slack_messenger import SlackMessenger

bcrypt = Bcrypt()
celery = FlaskCeleryExt()
csrf_protect = CsrfProtect()
login_manager = LoginManager()
db = SQLAlchemy()
Expand Down
8 changes: 8 additions & 0 deletions app/league/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ class Config(object):
'<a href="https://github.com/massgo/league">GitHub</a>.'
)
}
CELERY_BROKER_URL = os.environ.get('CELERY_BROKER_URL',
'redis://cache:6379/0')
CELERY_RESULT_BACKEND = os.environ.get('CELERY_RESULT_BACKEND',
'rpc://queue')


class ProdConfig(Config):
Expand Down Expand Up @@ -59,6 +63,10 @@ class DevConfig(Config):
ASSETS_DEBUG = True # Don't bundle/minify static assets
CACHE_TYPE = 'simple' # Can be "memcached", "redis", etc.
LEAGUE_ROOT_PASS = 'root'
CELERY_BROKER_URL = os.environ.get('CELERY_BROKER_URL',
'redis://localhost:6379/0')
CELERY_RESULT_BACKEND = os.environ.get('CELERY_RESULT_BACKEND',
'redis://localhost:6379/0')


class TestConfig(Config):
Expand Down
45 changes: 45 additions & 0 deletions app/league/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
"""Celery tasks."""
import math

from bs4 import BeautifulSoup
from celery import current_app
from celery.utils.log import get_task_logger
from requests import get

from league.models import Player

logger = get_task_logger(__name__)


@current_app.task
def hello_world():
"""Hello world task."""
return 'Hello world!'


@current_app.task
def sync_aga_data():
"""Update all local AGA data by scraping the AGA servers."""
for player in Player.get_players():
url = 'http://www.usgo.org/ratings-lookup-id?PlayerID={}'.format(
player.aga_id)
data = get(url)
soup = BeautifulSoup(data.text, 'html.parser')
columns = [col.text for col in soup.findAll('tr')[1].findAll('td')]
logger.debug('AGA Data: {}'.format(columns))

if not int(columns[0]) == player.aga_id:
continue
if columns[2] == '':
continue

rating = float(columns[2])
if rating > 0:
rank = math.floor(rating)
else:
rank = math.ceil(rating)

player.update(aga_rank=rank)

return
46 changes: 46 additions & 0 deletions app/league/templates/admin/aga_syncing.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

{% extends "layout.html" %}
{% block content %}
<div class="container-narrow">
<h1>AGA Syncing</h1>
<br/>
<button id="submit-button" type="submit" class="btn btn-primary">Sync AGA Data</button>
</div>
{% endblock %}

{% block js %}
<script>

var csrfToken = '{{ csrf_token() }}';

$msg_container = $('#error-container');
$msg_template = $('#msg-template');

function display_msgs(msgs, alert_type='warning') {
$msg_container.hide();
for (var attr in msgs) {
$msg_container.append($msg_template.html());
$alerts = $msg_container.children('.alert');
$new_alert = $alerts.last();
$new_alert.addClass('alert-' + alert_type);
$new_alert.append(msgs[attr]);
}
$msg_container.show();
}

$('#submit-button').click(function() {
var jqxhr = $.post({
url: '{{ url_for('api.queue_aga_sync') }}',
data: { csrf_token: csrfToken }
})
.done(function() {
display_msgs(['Job submitted!'], 'success');
})
.fail(function() {
display_msgs(['Job failed to submit!'], 'danger');
})
console.log(jqxhr);
});

</script>
{% endblock %}
1 change: 1 addition & 0 deletions app/league/templates/admin/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ <h1>Admin Settings</h1>
<a href="{{ url_for('admin.create_user') }}"><h3>Create user</h3></a>
<a href="{{ url_for('admin.manage_slack_integration') }}"><h3>Manage Slack integration</h3></a>
<a href="{{ url_for('admin.manage_site_settings') }}"><h3>Manage site settings</h3></a>
<a href="{{ url_for('admin.aga_syncing') }}"><h3>AGA Syncing</h3></a>
</div>
{% endblock %}
34 changes: 14 additions & 20 deletions app/league/templates/dashboard/games.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@
{% extends "layout.html" %}

{% block content %}
<!-- See http://stackoverflow.com/questions/18673860/defining-a-html-template-to-append-using-jquery -->
<script id="error-template" type="text/x-error-template">
<div class="alert alert-warning">
<a class="close" title="Close" href="#" data-dismiss="alert">&times;</a>
</div><!-- end .alert -->
</script>

<div class="modal fade" id="editor-modal" tabindex="-1" role="dialog" aria-labelledby="editor-title">
<div class="modal-dialog" role="document">
<form class="modal-content form-horizontal" id="editor">
Expand Down Expand Up @@ -130,18 +123,19 @@ <h1 class="page-header">Games</h1>
return moment.utc(remotedate, server_dt_format).utcOffset(local_tz).format(local_dt_format);
}

$error_container = $('#error-container');
$error_template = $('#error-template');
$msg_container = $('#error-container');
$msg_template = $('#msg-template');

function display_errors(errors) {
$error_container.hide();
for (var attr in errors) {
$error_container.append($error_template.html());
alerts = $error_container.children('.alert');
$new_alert = alerts[alerts.length -1];
$new_alert.append(attr + ' - ' + errors[attr]);
function display_msgs(msgs, alert_type='warning') {
$msg_container.hide();
for (var attr in msgs) {
$msg_container.append($msg_template.html());
$alerts = $msg_container.children('.alert');
$new_alert = $alerts.last();
$new_alert.addClass('alert-' + alert_type);
$new_alert.append(msgs[attr]);
}
$error_container.show();
$msg_container.show();
}

function format_player(value) {
Expand Down Expand Up @@ -182,7 +176,7 @@ <h1 class="page-header">Games</h1>
});
},
error: function(jqXHR, textStatus, errorThrown) {
display_errors(jqXHR.responseJSON);
display_msgs(jqXHR.responseJSON);
}
});
}
Expand Down Expand Up @@ -219,7 +213,7 @@ <h1 class="page-header">Games</h1>
});
},
error: function(jqXHR, textStatus, errorThrown) {
display_errors(jqXHR.responseJSON);
display_msgs(jqXHR.responseJSON);
}
});
}
Expand All @@ -233,7 +227,7 @@ <h1 class="page-header">Games</h1>
},
error: function(jqXHR, textStatus, errorThrown) {
if (jqXHR.status == 404) {
display_errors({'game_id': 'Game ' + id + ' could not be found and was not deleted.'});
display_msgs({'game_id': 'Game ' + id + ' could not be found and was not deleted.'});
}
}
});
Expand Down
7 changes: 7 additions & 0 deletions app/league/templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@
{% endwith %}

<header>{% block header %}{% endblock %}</header>
<!-- See http://stackoverflow.com/questions/18673860/defining-a-html-template-to-append-using-jquery -->
<script id="msg-template" type="text/x-error-template">
<div class="alert">
<a class="close" title="Close" href="#" data-dismiss="alert">&times;</a>
</div><!-- end .alert -->
</script>

<div class="{% block content_class %}container{% endblock content_class %}">

<div role="main">
Expand Down
2 changes: 1 addition & 1 deletion app/migrate_and_run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ do
sleep 1
done

uwsgi --chmod-socket=666 -s /tmp/uwsgi/uwsgi.sock --plugin python3 --manage-script-name --mount /=autoapp:app
uwsgi --chmod-socket=666 -s /tmp/uwsgi/uwsgi.sock --plugin python3 --manage-script-name --mount /=autoapp:flaskapp
10 changes: 10 additions & 0 deletions app/requirements/prod.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,13 @@ Flask-DebugToolbar==0.10.1

# Requests
requests==2.18.4

# Queue
celery==4.1.0
flask-celeryext==0.3.0

# Cache
redis==2.10.6

# BeautifulSoup
beautifulsoup4==4.6.0
Loading