Compare commits
8 Commits
master
...
developmen
Author | SHA1 | Date | |
---|---|---|---|
6f97bba84d | |||
efd36e4548 | |||
71b12a38f4 | |||
2d3e550b69 | |||
02b5033cce | |||
b4ea3e4165 | |||
2420f10cda | |||
7c3eade8dc |
@ -1,6 +1,5 @@
|
||||
import simplejson as json
|
||||
from datetime import datetime
|
||||
from random import choice
|
||||
from datetime import datetime, timedelta
|
||||
from flask.ext.sqlalchemy import SQLAlchemy
|
||||
from sqlalchemy.ext.mutable import Mutable
|
||||
|
||||
@ -69,16 +68,14 @@ class User(db.Model):
|
||||
|
||||
nickname = db.Column(db.String(80))
|
||||
avatar = db.Column(db.String(255))
|
||||
admin = db.Column(db.Boolean)
|
||||
|
||||
bio_text = db.Column(db.String(4096))
|
||||
created = db.Column(db.DateTime)
|
||||
last_seen = db.Column(db.DateTime)
|
||||
twitch = db.Column(db.String(60))
|
||||
hitbox = db.Column(db.String(60))
|
||||
random_heroes = db.Column(MutableDict.as_mutable(Json))
|
||||
az_completions = db.Column(db.Integer)
|
||||
|
||||
admin = db.Column(db.Boolean)
|
||||
public = db.Column(db.Boolean)
|
||||
logo = db.Column(db.Boolean)
|
||||
|
||||
@ -89,7 +86,8 @@ class User(db.Model):
|
||||
ts3_starttime = db.Column(db.DateTime)
|
||||
ts3_endtime = db.Column(db.DateTime)
|
||||
ts3_rewardtime = db.Column(db.DateTime)
|
||||
ts3_connections = db.Column(MutableDict.as_mutable(Json))
|
||||
ts3_stretch_award_time = db.Column(db.DateTime)
|
||||
ts3_longest_stretch = db.Column(db.Interval)
|
||||
|
||||
last_post_reward = db.Column(db.Integer)
|
||||
winrate_data = db.Column(MutableDict.as_mutable(Json))
|
||||
@ -114,10 +112,9 @@ class User(db.Model):
|
||||
|
||||
def __init__(self, steam_id):
|
||||
self.steam_id = steam_id
|
||||
self.random_heroes = {'current':None, 'completed':[]}
|
||||
self.az_completions = 0
|
||||
self.ts3_connections = {'list':[]}
|
||||
self.ts3_rewardtime = datetime.utcnow()
|
||||
self.ts3_longest_stretch = timedelta()
|
||||
self.created = datetime.utcnow()
|
||||
self.last_seen = datetime.utcnow()
|
||||
self.bio_text = None
|
||||
@ -127,64 +124,33 @@ class User(db.Model):
|
||||
self.admin = False
|
||||
self.public = True
|
||||
self.biglogo = True
|
||||
|
||||
@property
|
||||
def random_hero(self):
|
||||
if not self.random_heroes['current']:
|
||||
heroes = []
|
||||
for (tavern_name, tavern) in parse_valve_heropedia():
|
||||
heroes.extend([complete_hero_data('name', entry['name']) for entry in tavern if entry['name'] not in self.random_heroes['completed']])
|
||||
if heroes:
|
||||
self.random_heroes['current'] = choice(heroes)
|
||||
self.random_heroes = self.random_heroes
|
||||
db.session.commit()
|
||||
return self.random_heroes['current']
|
||||
|
||||
@random_hero.setter
|
||||
def random_hero(self, herodata):
|
||||
self.random_heroes['current'] = herodata
|
||||
self.random_heroes = self.random_heroes
|
||||
db.session.commit()
|
||||
|
||||
@property
|
||||
def random_completed(self):
|
||||
return self.random_heroes['completed']
|
||||
|
||||
def random_success(self):
|
||||
self.random_heroes['completed'].append(self.random_heroes['current']['name'])
|
||||
if len(API_DATA['result']['heroes']) - len(self.random_heroes['completed']) <= 0:
|
||||
self.az_completions = self.az_completions + 1
|
||||
del self.random_heroes['completed'][:]
|
||||
self.random_heroes['current'] = None
|
||||
self.random_heroes = self.random_heroes
|
||||
db.session.commit()
|
||||
return self.random_hero
|
||||
|
||||
def random_skip(self):
|
||||
self.random_heroes['current'] = None
|
||||
self.random_heroes = self.random_heroes
|
||||
db.session.commit()
|
||||
return self.random_hero
|
||||
|
||||
def update_connection(self, reward_threshold=30):
|
||||
now = datetime.utcnow()
|
||||
self.ts3_starttime = self.ts3_starttime or now
|
||||
self.ts3_endtime = now
|
||||
|
||||
# Add general TS3 points here
|
||||
if self.ts3_endtime and self.ts3_rewardtime:
|
||||
delta = (self.ts3_endtime - self.ts3_rewardtime)
|
||||
duration = (delta.seconds % 3600) // 60
|
||||
if duration > reward_threshold:
|
||||
self.ts3_rewardtime = datetime.utcnow()
|
||||
self.points_from_ts3 += 1
|
||||
else:
|
||||
self.ts3_rewardtime = datetime.utcnow()
|
||||
delta = (self.ts3_endtime - self.ts3_rewardtime)
|
||||
duration = (delta.seconds % 3600) // 60
|
||||
if duration > reward_threshold:
|
||||
self.ts3_rewardtime = datetime.utcnow()
|
||||
self.points_from_ts3 += 1
|
||||
|
||||
# Update last_seen for web profile
|
||||
self.last_seen = datetime.utcnow()
|
||||
db.session.commit();
|
||||
|
||||
def finalize_connection(self):
|
||||
self.ts3_connections['list'].append({'starttime': self.ts3_starttime, 'endtime': self.ts3_endtime})
|
||||
self.ts3_startime = None
|
||||
# Check for longest!
|
||||
if self.ts3_endtime and self.ts3_starttime:
|
||||
current_stretch = self.ts3_endtime - self.ts3_starttime
|
||||
if current_stretch > self.ts3_longest_stretch:
|
||||
self.ts3_longest_stretch = current_stretch
|
||||
self.ts3_stretch_award_time = datetime.utcnow()
|
||||
|
||||
# Reset values
|
||||
self.ts3_starttime = None
|
||||
self.ts3_endtime = None
|
||||
db.session.commit();
|
||||
|
||||
@ -193,6 +159,7 @@ class User(db.Model):
|
||||
posts = board.Users.select().where(board.Users.id == int(self.forum_id))[0].posts
|
||||
if self.last_post_reward:
|
||||
num_points = (posts - self.last_post_reward) / reward_threshold
|
||||
print("Old: {0}, New: {1}, ({0} - {1}) / {2}, {3}, {4}".format(self.last_post_reward, posts, reward_threshold, num_points, self.nickname))
|
||||
if num_points > 0:
|
||||
self.points_from_forum += num_points
|
||||
self.last_post_reward += num_points * reward_threshold
|
||||
@ -308,7 +275,7 @@ class Event(db.Model):
|
||||
@property
|
||||
def expired(self):
|
||||
current_time = datetime.utcnow()
|
||||
return self.end_time < curent_time
|
||||
return self.end_time < current_time
|
||||
|
||||
def add_participant(self, user):
|
||||
entry = self.participants.setdefault(user, {'start_time': datetime.utcnow() })
|
||||
|
@ -348,6 +348,7 @@ def award_idle_ts3_points(server):
|
||||
for channel in list_response.data:
|
||||
if exempt_check(channel['cid']):
|
||||
exempt_cids.append(channel['cid'])
|
||||
|
||||
# Get list of clients
|
||||
clientlist = server.clientlist()
|
||||
for clid, client in clientlist.iteritems():
|
||||
@ -366,6 +367,7 @@ def award_idle_ts3_points(server):
|
||||
active_users.add(doob)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
doobs = set(models.User.query.filter(models.User.ts3_starttime != None).all())
|
||||
for doob in doobs.intersection(active_users):
|
||||
for doob in doobs.difference(active_users):
|
||||
doob.finalize_connection()
|
||||
|
@ -1,89 +0,0 @@
|
||||
{% extends "layout.html" %}
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/heropedia.css') }}" >
|
||||
{% endblock %}
|
||||
|
||||
{% block title %} A-Z Challenge: {{ user.nickname }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% set taverns = heropedia() %}
|
||||
<h2 class="uk-text-center">{{ user.nickname }}'s A-Z Challenge</h2>
|
||||
<hr />
|
||||
<div class="uk-grid">
|
||||
<div class="uk-width-large-1-3 uk-width-medium-1-1 uk-panel uk-text-center uk-margin-bottom">
|
||||
<h3 class="uk-panel-title">Current Hero</h3>
|
||||
<h4 class="uk-text-bold uk-margin-remove">{{ user.random_hero['localized_name'] }}</h4>
|
||||
<img src="{{ url_for('static', filename=hero_image_large(user.random_hero)) }}" class="dn-hero-icon" />
|
||||
|
||||
<p>
|
||||
<span id="heroes_completed">Heroes Completed: {{ user.random_heroes.completed | length }}</span><br/>
|
||||
<span id="heroes_left">Heroes Left: {{ total_hero_pool() - user.random_heroes.completed|length }}</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
{% if g.user and g.user.steam_id == user.steam_id %}
|
||||
<form action="{{ url_for('user_random_hero', userid=g.user.id) }}" method="post" id="random_form" class="uk-margin">
|
||||
<input type="checkbox" name="completed" id="completed_checkbox" style="display:none;">
|
||||
<input type="checkbox" name="skip" id="skip_checkbox" style="display:none;">
|
||||
<a class="uk-button uk-button-success" id="completed_button">Completed!</a>
|
||||
<a class="uk-button uk-button-primary" id="skip_button">Skip</a>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="uk-width-large-2-3 uk-width-medium-1-1 uk-panel uk-text-center uk-margin">
|
||||
{% if user.az_completions > 0 %}
|
||||
<div class="uk-badge uk-panel-badge uk-badge-notification uk-badge-success">x{{ user.az_completions }}</div>
|
||||
{% endif %}
|
||||
<h3 class="uk-panel-title">Completed</h3>
|
||||
{% for hero in user.random_heroes.completed %}
|
||||
<img src="{{ url_for('static', filename=hero_image_small(hero)) }}" class="dn-hero-icon" />
|
||||
{% endfor %}
|
||||
<br/><br/>
|
||||
<br/><br/>
|
||||
</div>
|
||||
<div class="uk-width-large-2-3 uk-width-medium-1-1 uk-container-center">
|
||||
<ul class="uk-tab" data-uk-tab="{connect:'#taverns'}">
|
||||
<li class="uk-active"><a href="">Strength</a></li>
|
||||
<li><a href="">Agility</a></li>
|
||||
<li><a href="">Intelligence</a></li>
|
||||
</ul>
|
||||
<ul id="taverns" class="uk-switcher uk-margin">
|
||||
<li><div class="uk-panel tavern">
|
||||
<label id="tavernStrength">Strength</label>
|
||||
{% for hero in taverns[0][1] + taverns[3][1] %}
|
||||
<img class="{{hero['name'] in user.random_completed and 'filterUnmatchedHero' or 'filterMatchedHero' }}" id="{{ hero['name'] }}" src="{{ url_for('static', filename=hero_image_small(hero)) }}" />
|
||||
{% endfor %}
|
||||
</div></li>
|
||||
<li><div class="uk-panel tavern">
|
||||
<label id="tavernAgility">Agility</label>
|
||||
{% for hero in taverns[1][1] + taverns[4][1] %}
|
||||
<img class="{{hero['name'] in user.random_completed and 'filterUnmatchedHero' or 'filterMatchedHero' }}" id="{{ hero['name'] }}" src="{{ url_for('static', filename=hero_image_small(hero)) }}" />
|
||||
{% endfor %}
|
||||
</div> </li>
|
||||
<li><div class="uk-panel tavern">
|
||||
<label id="tavernIntelligence">Intelligence</label>
|
||||
{% for hero in taverns[2][1] + taverns[5][1] %}
|
||||
<img class="{{hero['name'] in user.random_completed and 'filterUnmatchedHero' or 'filterMatchedHero' }}" id="{{ hero['name'] }}" src="{{ url_for('static', filename=hero_image_small(hero)) }}" />
|
||||
{% endfor %}
|
||||
</div> </li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% if g.user and g.user.id == user.id %}
|
||||
{% block pagescripts %}
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#completed_button').click( function() {
|
||||
$('#completed_checkbox').attr('checked', true);
|
||||
$('#random_form').submit();
|
||||
});
|
||||
$('#skip_button').click( function() {
|
||||
$('#skip_checkbox').attr('checked', true);
|
||||
$('#random_form').submit();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% endif %}
|
@ -35,7 +35,6 @@
|
||||
<div class="uk-dropdown uk-dropdown-navbar">
|
||||
<ul class="uk-nav uk-nav-navbar">
|
||||
<li><a href="{{ url_for('user_profile', userid=g.user.id) }}">Profile</a></li>
|
||||
<li><a href="{{ url_for('user_random_hero', userid=g.user.id) }}">A-Z Challenge</a></li>
|
||||
<li><a href="http://board.dotanoobs.com/?page=lastposts">Latest Posts</a></li>
|
||||
{% if g.user.admin %}
|
||||
<li><a href="{{ url_for('event_edit') }}">Add Event</a></li>
|
||||
|
@ -15,16 +15,7 @@
|
||||
</div>
|
||||
<!-- Side bar -->
|
||||
<div class="uk-width-large-1-3 uk-width-medium-1-1 uk-panel uk-panel-box uk-panel-box-secondary">
|
||||
<div class="uk-container-center uk-text-center">
|
||||
<span class="uk-text-bold">Current Hero</span><br/>
|
||||
<span>{{ user.random_hero['localized_name'] }}</span><br/>
|
||||
<a href={{ url_for('user_random_hero', userid=user.id) }}>
|
||||
<img src="{{ url_for('static', filename=hero_image_large(user.random_hero)) }}" class="dn-hero-icon" /><br/>
|
||||
<span>View A-Z Progress</span>
|
||||
</a>
|
||||
</div>
|
||||
<ul class="uk-list uk-list-space uk-list-striped uk-text-center">
|
||||
<li>Completed <span id='rands'>{{ user.random_heroes.completed | length }}</span> heroes in A-Z</li>
|
||||
<li>Has <span id='points_total'>0</span> doobs points</li>
|
||||
<li>Last seen at <span class='date'> {{ user.last_seen | js_datetime }}</span></li>
|
||||
<li>Doob since <span class='date'> {{ user.created | js_datetime }}</span></li>
|
||||
|
@ -45,19 +45,6 @@
|
||||
<!-- Side bar -->
|
||||
<div class="uk-width-large-1-3 uk-width-medium-1-1 uk-panel">
|
||||
{% if user.public %}
|
||||
<div class="uk-container-center uk-text-center">
|
||||
<span class="uk-text-bold">Current Hero</span><br/>
|
||||
<span class="uk-text-success uk-text-bold">
|
||||
{{ user.random_hero['localized_name'] }}
|
||||
({{ user.random_heroes.completed | length + 1 }}
|
||||
/
|
||||
{{ total_hero_pool() - user.random_heroes.completed|length }})
|
||||
</span><br/>
|
||||
<a href={{ url_for('user_random_hero', userid=user.id) }}>
|
||||
<img src="{{ url_for('static', filename=hero_image_large(user.random_hero)) }}" class="dn-hero-icon" /><br/>
|
||||
<span>View A-Z Progress</span>
|
||||
</a>
|
||||
</div>
|
||||
<table class="uk-table uk-table-hover uk-table-condensed">
|
||||
<caption>{{ user.nickname }}</caption>
|
||||
<tbody class="uk-text-small">
|
||||
@ -83,12 +70,6 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% if not user.winrate_data['data'] %}
|
||||
<h3 class="uk-text-warning">No data compiled, check back tomorrow!</h3>
|
||||
<button class="uk-button uk-button-success uk-align-center" data-uk-modal="{target: '#winrate_modal'}" disabled>View Winrate</button>
|
||||
{% else %}
|
||||
<button class="uk-button uk-button-success uk-align-center" data-uk-modal="{target: '#winrate_modal'}">View Winrate</button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
18
app/views.py
18
app/views.py
@ -56,7 +56,7 @@ def create_or_login(resp):
|
||||
match = app.config['STEAM_ID_RE'].search(resp.identity_url)
|
||||
g.user = User.get_or_create(match.group(1))
|
||||
steamdata = get_steam_userinfo(g.user.steam_id)
|
||||
g.user.nickname = steamdata['personaname']
|
||||
g.user.nickname = steamdata['personaname'].encode('utf-8', 'replace')
|
||||
g.user.avatar = steamdata['avatar']
|
||||
db.session.commit()
|
||||
session['user_id'] = g.user.id
|
||||
@ -80,28 +80,12 @@ def teamspeak():
|
||||
def friends():
|
||||
return render_template('friends.html')
|
||||
|
||||
# Stream pages
|
||||
@app.route('/shaneomad')
|
||||
def twitch_shaneomad():
|
||||
return render_template('potatr.html', twitch_id=app.config.TWITCH_CLIENT_ID)
|
||||
|
||||
# User profile page
|
||||
@app.route('/user/<int:userid>')
|
||||
def user_profile(userid):
|
||||
user = User.query.filter_by(id=userid).first_or_404()
|
||||
return render_template('profile.html', user=user)
|
||||
|
||||
# User random a-z challenge progress page
|
||||
@app.route('/user/<int:userid>/random', methods=['POST', 'GET'])
|
||||
def user_random_hero(userid):
|
||||
user = User.query.filter_by(id=userid).first_or_404()
|
||||
if request.method == 'POST':
|
||||
if request.form.get('skip', False):
|
||||
user.random_skip()
|
||||
elif request.form.get('completed', False):
|
||||
user.random_success()
|
||||
return render_template('hero_random.html', user=user)
|
||||
|
||||
# User settings page
|
||||
@app.route('/settings', methods=['POST', 'GET'])
|
||||
@login_required
|
||||
|
34
migrations/versions/50e77b6e7331_.py
Normal file
34
migrations/versions/50e77b6e7331_.py
Normal file
@ -0,0 +1,34 @@
|
||||
"""empty message
|
||||
|
||||
Revision ID: 50e77b6e7331
|
||||
Revises: 9e520de441f
|
||||
Create Date: 2014-11-17 13:21:23.705195
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '50e77b6e7331'
|
||||
down_revision = '9e520de441f'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import mysql
|
||||
|
||||
def upgrade():
|
||||
### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('user', sa.Column('ts3_longest_stretch', sa.Interval(), nullable=True))
|
||||
op.add_column('user', sa.Column('ts3_stretch_award_time', sa.DateTime(), nullable=True))
|
||||
op.drop_column('user', u'random_heroes')
|
||||
op.drop_column('user', u'ts3_connections')
|
||||
op.drop_column('user', u'az_completions')
|
||||
### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('user', sa.Column(u'az_completions', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True))
|
||||
op.add_column('user', sa.Column(u'ts3_connections', mysql.TEXT(), nullable=True))
|
||||
op.add_column('user', sa.Column(u'random_heroes', mysql.TEXT(), nullable=True))
|
||||
op.drop_column('user', 'ts3_stretch_award_time')
|
||||
op.drop_column('user', 'ts3_longest_stretch')
|
||||
### end Alembic commands ###
|
@ -9,7 +9,7 @@ Flask-WTF==0.9.4
|
||||
Jinja2==2.7.1
|
||||
Mako==1.0.0
|
||||
MarkupSafe==0.18
|
||||
MySQL-python==1.2.4
|
||||
MySQL-python==1.2.5
|
||||
Pygments==1.6
|
||||
SQLAlchemy==0.8.4
|
||||
WTForms==1.0.5
|
||||
@ -24,13 +24,12 @@ ipdb==0.8
|
||||
ipython==2.1.0
|
||||
itsdangerous==0.23
|
||||
nose==1.3.3
|
||||
numpy==1.8.1
|
||||
peewee==2.1.6
|
||||
pyparsing==2.0.2
|
||||
python-crontab==1.8.1
|
||||
python-dateutil==2.2
|
||||
python-openid==2.2.5
|
||||
python-ts3==0.1
|
||||
#python-ts3==0.1
|
||||
pytz==2014.4
|
||||
requests==2.1.0
|
||||
simplejson==3.3.1
|
||||
|
14
run.py
14
run.py
@ -57,7 +57,15 @@ def install_cronjobs():
|
||||
print "Problem installing cronjobs: {}".format(e)
|
||||
else:
|
||||
cron.write()
|
||||
print "Cron jobs written succesfully"
|
||||
print "Cron jobs written successfully"
|
||||
|
||||
@manager.command
|
||||
def delete_cronjobs():
|
||||
from os import path
|
||||
from crontab import CronTab
|
||||
cron = CronTab(user=True)
|
||||
cron.remove_all(comment='DOOBSAUTO')
|
||||
print "Existing cronjobs deleted successfully"
|
||||
|
||||
@manager.command
|
||||
def admin(name):
|
||||
@ -96,6 +104,10 @@ def ts3_process_events():
|
||||
tsServer = createTeamspeakInstance()
|
||||
process_ts3_events(tsServer)
|
||||
|
||||
@manager.command
|
||||
def forum_award_points():
|
||||
for user in models.User.query.filter(models.User.forum_id != None).all():
|
||||
user.update_forum_posts()
|
||||
|
||||
if __name__ == '__main__':
|
||||
manager.run()
|
||||
|
Loading…
x
Reference in New Issue
Block a user