Fixed MutableDict. Redesigned profile,random,settings. Added user bios
This commit is contained in:
parent
bc52fc0660
commit
23e04edafd
2
.gitignore
vendored
2
.gitignore
vendored
@ -3,4 +3,4 @@ __pycache__/
|
||||
*.py[cod]
|
||||
|
||||
*.so
|
||||
|
||||
static/img/hero-images/*.png
|
||||
|
@ -227,4 +227,4 @@ def utility_processor():
|
||||
country_abbreviation_mapping=country_abbreviation_mapping)
|
||||
|
||||
|
||||
'''
|
||||
'''
|
||||
|
7
forms.py
Normal file
7
forms.py
Normal file
@ -0,0 +1,7 @@
|
||||
from flask.ext.wtf import Form
|
||||
from wtforms import TextField, BooleanField, TextAreaField
|
||||
|
||||
class SettingsForm(Form):
|
||||
public = BooleanField('public', default=True)
|
||||
twitch = TextField('twitch')
|
||||
bio_text = TextAreaField('bio_text')
|
99
models.py
99
models.py
@ -1,35 +1,110 @@
|
||||
import simplejson as json
|
||||
from random import choice
|
||||
from flask.ext.sqlalchemy import SQLAlchemy
|
||||
from sqlalchemy.ext.mutable import Mutable
|
||||
from time import time
|
||||
from app import db
|
||||
from utils import parse_valve_heropedia, complete_hero_data
|
||||
|
||||
# Get a little of that Mongoness back
|
||||
class Json(db.TypeDecorator):
|
||||
impl = db.Unicode
|
||||
impl = db.Text
|
||||
|
||||
def process_bind_param(self, value, dialect):
|
||||
if value is not None:
|
||||
value = json.dumps(value)
|
||||
return value
|
||||
|
||||
def process_result_value(self, value, dialect):
|
||||
if value is not None:
|
||||
value = json.loads(value)
|
||||
return value
|
||||
|
||||
|
||||
class MutableDict(Mutable, dict):
|
||||
@classmethod
|
||||
def coerce(cls, key, value):
|
||||
if not isinstance(value, MutableDict):
|
||||
if isinstance(value, dict):
|
||||
return MutableDict(value)
|
||||
return Mutable.coerce(key,value)
|
||||
else:
|
||||
return value
|
||||
|
||||
def __delitem__(self, key):
|
||||
dict.__delitem__(self, key)
|
||||
self.changed()
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
dict.__setitem__(self, key, value)
|
||||
self.changed()
|
||||
|
||||
def __getstate__(self):
|
||||
return dict(self)
|
||||
|
||||
def __setstate__(self, state):
|
||||
self.update(self)
|
||||
|
||||
def process_bind_param(self, value, dialect):
|
||||
return unicode(json.dumps(value))
|
||||
|
||||
def process_result_value(self, value, dialect):
|
||||
return json.loads(value)
|
||||
|
||||
class User(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
steam_id = db.Column(db.String(40), unique=True)
|
||||
nickname = db.Column(db.String(80))
|
||||
avatar = db.Column(db.String(255))
|
||||
random_heroes = db.Column(MutableDict.as_mutable(Json))
|
||||
bio_text = db.Column(db.String(4096))
|
||||
last_seen = db.Column(db.DateTime)
|
||||
twitch = db.Column(db.String(60))
|
||||
|
||||
@staticmethod
|
||||
def get_or_create(steam_id):
|
||||
rv = User.query.filter_by(steam_id=steam_id).first()
|
||||
if rv is None:
|
||||
rv = User()
|
||||
rv.steam_id = steam_id
|
||||
db.session.add(rv)
|
||||
return rv
|
||||
rv = User.query.filter_by(steam_id=steam_id).first()
|
||||
if rv is None:
|
||||
rv = User()
|
||||
rv.steam_id = steam_id
|
||||
rv.random_heroes = {'current':None, 'completed':[]}
|
||||
bio_text = ''
|
||||
db.session.add(rv)
|
||||
return rv
|
||||
|
||||
@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 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'])
|
||||
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 __repr__(self):
|
||||
return '<User {}>'.format(self.steam_id)
|
||||
return '<User {}>'.format(self.nickname)
|
||||
|
||||
class TeamspeakData(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
|
1250
static/country_codes.xml
Normal file
1250
static/country_codes.xml
Normal file
File diff suppressed because it is too large
Load Diff
@ -6,14 +6,9 @@ body {
|
||||
margin: 1em auto 6em;
|
||||
}
|
||||
#biglogo {
|
||||
width:75%;
|
||||
}
|
||||
.dark-panel {
|
||||
background: -moz-linear-gradient(center top, #222222 0%, #313331 100%);
|
||||
border: 5px solid #999999;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,0.25);
|
||||
color: #fff;
|
||||
width:65%;
|
||||
max-width:650px;
|
||||
min-width:250px;
|
||||
}
|
||||
.uk-navbar-brand > img, .uk-navbar-flip > img {
|
||||
height:35px;
|
||||
@ -58,3 +53,30 @@ footer {
|
||||
#streams-online > .uk-article > a > h4 {
|
||||
margin:0px;
|
||||
}
|
||||
#tsviewer > .uk-modal-dialog {
|
||||
max-height: 80%;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.ts_num {
|
||||
color: #D9A859;
|
||||
}
|
||||
.dn-streamer, .dn-streamer-offline {
|
||||
display: inline-block;
|
||||
width: 110px;
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
}
|
||||
.dn-streamer-offline > img {
|
||||
height:50px;
|
||||
}
|
||||
|
||||
.dn-streamer-hover {
|
||||
background:red;
|
||||
}
|
||||
|
||||
.dn-hero-icon {
|
||||
background:#000;
|
||||
padding:4px;
|
||||
margin:2px;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
background-repeat:no-repeat;
|
||||
overflow:visible;
|
||||
text-transform:uppercase;
|
||||
color: rgba(105,211,50,0.75);
|
||||
color: black;
|
||||
padding:6px 10px 15px 40px;
|
||||
}
|
||||
#tavernAgility{
|
||||
|
@ -20,11 +20,10 @@
|
||||
{
|
||||
font-family: sans-serif;
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
white-space: normal;
|
||||
width: 100%;
|
||||
line-height: 1;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tswv-link
|
||||
|
@ -8,10 +8,10 @@ from flask import url_for
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
from app import app
|
||||
from models import TeamspeakData
|
||||
|
||||
def getTeamspeakWindow(window=605800):
|
||||
current_time = time.time()
|
||||
from models import TeamspeakData
|
||||
return TeamspeakData.query.filter(TeamspeakData.time < current_time, TeamspeakData.time > current_time-window).order_by(TeamspeakData.time).all()
|
||||
|
||||
def create_teamspeak_viewer():
|
||||
@ -159,8 +159,11 @@ def create_teamspeak_viewer():
|
||||
return "error: %s" % inst
|
||||
|
||||
def get_ISO3166_mapping():
|
||||
data = requests.get('http://www.iso.org/iso/home/standards/country_codes/country_names_and_code_elements_xml.html')
|
||||
xml = ElementTree.fromstring(data.text.encode('utf-8'))
|
||||
#data = requests.get(url_for('static', filename='country_codes.xml'))
|
||||
#xml = ElementTree.fromstring(data.text.encode('utf-8'))
|
||||
with open('app/static/country_codes.xml', mode='r') as d:
|
||||
data = d.read()
|
||||
xml = ElementTree.fromstring(data)
|
||||
d = dict()
|
||||
for entry in xml.findall('ISO_3166-1_Entry'):
|
||||
d[entry.find('ISO_3166-1_Alpha-2_Code_element').text] = entry.find('ISO_3166-1_Country_name').text
|
||||
|
87
templates/hero_random.html
Normal file
87
templates/hero_random.html
Normal file
@ -0,0 +1,87 @@
|
||||
{% 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.steamid == user.steamid %}
|
||||
<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">
|
||||
<div class="uk-badge uk-panel-badge uk-badge-notification uk-badge-success">x1</div>
|
||||
<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 %}
|
@ -5,163 +5,128 @@
|
||||
{% block title %}Dota Noobs{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% cache 60*5 %}
|
||||
{#{% cache 60*5 %}#}
|
||||
{% set teamspeak_data = get_teamspeak_window() %}
|
||||
<div class="uk-grid" data-uk-grid-margin>
|
||||
<div class="uk-width-large-1-2 uk-width-medium-1-1">
|
||||
<div class=" uk-panel uk-panel-space">
|
||||
<h1 class="uk-panel-title">Who Are The Doobs!?</h1>
|
||||
<p>Welcome to DotaNoobs! We are a community formed by a group of redditors in an effort to provide a fun and rage-free environment for Dota2 players of all skill levels to enjoy the game and learn from each other. We have a TeamSpeak server open to the public for voice communication; hopping into the server is the best way to get involved, so click on "Server" to the right to get started. </p>
|
||||
<div id="about-us-more">
|
||||
<p>Be sure to visit the forum board to keep in touch with the community even when not playing. Create an account, introduce yourself, and chat about all things DotA.</p>
|
||||
<p>There is a "Dota Noobs" chat room inside the game client, and a "DotaNoobs" guild to help organzie games outside of TeamSpeak. Ask an admin for an invite today!</p>
|
||||
</div>
|
||||
<button class="uk-button uk-button-small uk-float-right" id="more">More <i class="uk-icon-angle-down"></i></button>
|
||||
<button class="uk-button uk-button-small uk-float-right" id="less">Less <i class="uk-icon-angle-up"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-width-large-1-2 uk-width-medium-1-1">
|
||||
<div class="uk-panel uk-panel-space uk-panel-box">
|
||||
<a href="ts3server://voice.dotanoobs.com"><div class="uk-panel-badge uk-badge uk-badge-success"><i class="uk-icon-microphone"> Connect to Teamspeak</i></div></a>
|
||||
<h1 class="uk-panel-title">Our TeamSpeak Server</h1>
|
||||
<ul>
|
||||
<li>Current Users: {{ ts3_current_clients() }}</li>
|
||||
<li>Active Countries: {{ ts3_countries_active(teamspeak_data) }}</li>
|
||||
</ul>
|
||||
<button class="uk-button" data-uk-modal="{target:'#tsviewer'}">Viewer</button>
|
||||
<a class="uk-button" href="{{ url_for('teamspeak') }}">Statistics</a>
|
||||
|
||||
<hr class="uk-panel-divider" />
|
||||
|
||||
|
||||
<h1 class="uk-panel-title">Events</h1>
|
||||
{#
|
||||
{% if active_event %}
|
||||
<article class="uk-article">
|
||||
<h4>Right Now</h4>
|
||||
<a href="{{ url_for('event_summary', eventid=active_event._id) }}">{{ active_event.name }}</a>
|
||||
<p class="uk-article-meta">Ends at: {{ timestamp_to_js_date(active_event.end_time) }}</p>
|
||||
</article>
|
||||
{% endif %}
|
||||
{% if upcoming_event %}
|
||||
<article class="uk-article">
|
||||
<h4>Next Event</h4>
|
||||
<a href="{{ url_for('event_summary', eventid=upcoming_event._id) }}">{{ upcoming_event.name }}</a>
|
||||
<p class="uk-article-meta">Starts at: {{ timestamp_to_js_date(upcoming_event.start_time) }}</p>
|
||||
</article>
|
||||
{% else %}
|
||||
<em>No events planned for the near future. Suggest one on the forum!</em>
|
||||
{% endif %}
|
||||
#}
|
||||
<div class="uk-grid">
|
||||
<div class="uk-width-large-1-2 uk-width-medium-1-1 uk-panel uk-panel-space">
|
||||
<h1 class="uk-panel-title">Events</h1>
|
||||
{#
|
||||
{% if active_event %}
|
||||
<article class="uk-article">
|
||||
<h4>Right Now</h4>
|
||||
<a href="{{ url_for('event_summary', eventid=active_event._id) }}">{{ active_event.name }}</a>
|
||||
<p class="uk-article-meta">Ends at: {{ timestamp_to_js_date(active_event.end_time) }}</p>
|
||||
</article>
|
||||
{% endif %}
|
||||
{% if upcoming_event %}
|
||||
<article class="uk-article">
|
||||
<h4>Next Event</h4>
|
||||
<a href="{{ url_for('event_summary', eventid=upcoming_event._id) }}">{{ upcoming_event.name }}</a>
|
||||
<p class="uk-article-meta">Starts at: {{ timestamp_to_js_date(upcoming_event.start_time) }}</p>
|
||||
</article>
|
||||
{% else %}
|
||||
<em>No events planned for the near future. Suggest one on the forum!</em>
|
||||
{% endif %}
|
||||
#}
|
||||
<em>No events planned for the near future. Suggest one on the forum!</em>
|
||||
</div>
|
||||
<div class="uk-width-large-1-2 uk-width-medium-1-1 uk-panel uk-panel-box uk-text-center">
|
||||
<a href="#" data-uk-modal="{target: '#tsviewer'}"><div class="uk-badge uk-panel-badge uk-badge-success"><i class="uk-icon-user"></i> Users</div></a>
|
||||
<h1 class="uk-panel-title">Teamspeak</h1>
|
||||
<div class="uk-grid uk-margin-bottom">
|
||||
<div class="uk-width-1-3 uk-panel">
|
||||
<h3>Users<br/><span class="ts_num">{{ ts3_current_clients() }}</span></h3>
|
||||
</div>
|
||||
<div class="uk-width-1-3 uk-panel">
|
||||
<h3 class="uk-text-success">Online</h3>
|
||||
</div>
|
||||
<div class="uk-width-1-3 uk-panel">
|
||||
<h3>Countries<br/><span class="ts_num">{{ ts3_countries_active(teamspeak_data) }}</span></h3>
|
||||
</div>
|
||||
</div>
|
||||
<div id="tsviewer" class="uk-modal">
|
||||
|
||||
<a class="uk-button uk-button-success uk-width-1-1" href="ts3server://voice.dotanoobs.com"><i class="uk-icon-microphone"></i> Connect</a>
|
||||
<a class="uk-button uk-width-1-1 uk-margin" href="{{ url_for('teamspeak') }}"><i class="uk-icon-globe"></i> Stats</a>
|
||||
<a class="uk-button uk-width-1-1" href="http://www.teamspeak.com/?page=downloads"><i class="uk-icon-download"></i> Download</a>
|
||||
|
||||
<div id="tsviewer" class="uk-modal uk-text-left">
|
||||
<div class="uk-modal-dialog">
|
||||
<a class="uk-modal-close uk-close"></a>
|
||||
{{ ts3_viewer() | safe }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="streams" class="uk-width-1-1 uk-text-center uk-panel uk-panel-space">
|
||||
</div>
|
||||
|
||||
<div class="uk-width-1-1 uk-panel uk-panel-header">
|
||||
<h4 class="uk-panel-title">News and Announcements</h4>
|
||||
{% for news in latest_news %}
|
||||
<article class="uk-article dn-news-article">
|
||||
<h4 class="uk-article-title" title="{{ news['title'] }}"><a href="{{ news['url'] }}">{{ news['title'] }}</a></h4>
|
||||
<p class="uk-article-meta">{{ news['date'] }}</p>
|
||||
<p>{{ news['text'] | shorten }}</p>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-grid" data-uk-grid-margin>
|
||||
<div class="uk-width-large-2-3 uk-width-medium-1-1">
|
||||
<div class="uk-panel uk-panel-space uk-panel-box uk-panel-header">
|
||||
<h1 class="uk-panel-title">News and Announcements</h1>
|
||||
{% for news in latest_news %}
|
||||
<article class="uk-article dn-news-article">
|
||||
<h4 class="uk-article-title uk-text-truncate" data-uk-tooltip="{pos:'bottom-right'}" title="{{ news['title'] }}"><a href="{{ news['url'] }}">{{ news['title'] }}</a></h4>
|
||||
<p class="uk-article-meta">{{ news['date'] }}</p>
|
||||
<p>{{ news['text'] | shorten }}</p>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{#
|
||||
<div class="uk-hidden-large uk-width-medium-1-1">
|
||||
<div class="uk-panel uk-panel-space uk-panel-box uk-panel-header">
|
||||
<a href="{{ url_for('list_events') }}"><div class="uk-panel-badge uk-badge uk-badge-success"><i class="uk-icon-calendar"> View All Events</i></div></a>
|
||||
<h1 class="uk-panel-title">Events</h1>
|
||||
{% if active_event %}
|
||||
<article class="uk-article">
|
||||
<h4>Right Now</h4>
|
||||
<a href="{{ url_for('event_summary', eventid=active_event._id) }}">{{ active_event.name }}</a>
|
||||
<p class="uk-article-meta">Ends at: {{ timestamp_to_js_date(active_event.end_time) }}</p>
|
||||
</article>
|
||||
{% endif %}
|
||||
{% if upcoming_event %}
|
||||
<article class="uk-article">
|
||||
<h4>Next Event</h4>
|
||||
<a href="{{ url_for('event_summary', eventid=upcoming_event._id) }}">{{ upcoming_event.name }}</a>
|
||||
<p class="uk-article-meta">Starts at: {{ timestamp_to_js_date(upcoming_event.start_time) }}</p>
|
||||
</article>
|
||||
{% else %}
|
||||
<em>No events planned for the near future. Suggest one on the forum!</em>
|
||||
{% endif %}
|
||||
<em>No events planned for the near future. Suggest one on the forum!</em>
|
||||
</div>
|
||||
</div>
|
||||
#}
|
||||
<div class="uk-width-large-1-3 uk-width-medium-1-1">
|
||||
<div class="uk-panel uk-panel-space">
|
||||
<h1 class="uk-panel-title">Live Streams</h1>
|
||||
<ul id="streams-online"></ul>
|
||||
<hr id="stream-divider" class="uk-article-divider" style="display:none;" />
|
||||
<ul id="streams-offline"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endcache %}
|
||||
{#{% endcache %}#}
|
||||
{% endblock %}
|
||||
|
||||
{% block pagescripts %}
|
||||
<script>
|
||||
{% cache 60*5 %}
|
||||
$(document).ready(function() {
|
||||
{% cache 60*5 %}
|
||||
// Add the streams
|
||||
var stream_url = "https://api.twitch.tv/kraken/streams/";
|
||||
var channels = ["dotanoobs", "bearhugdota", "kreejaffakree", "prettypenguins", "shaneomad"];
|
||||
for (var idx in channels) {
|
||||
$.getJSON(stream_url+channels[idx]+"?callback=?", function(data) {
|
||||
if (data.stream) {
|
||||
$('#streams-online').append("<article class='uk-article' id='" + data.stream.channel.name + "'>");
|
||||
var jquery_selector = '#'+data.stream.channel.name;
|
||||
$(jquery_selector).append("<a href='"+data.stream.channel.url+"'><h4>" + data.stream.channel.display_name + "</h4></a>")
|
||||
var span_text = "<span class='uk-article-meta'>";
|
||||
span_text = span_text + "Playing: " + data.stream.game + "<br />";
|
||||
span_text = span_text + "Viewers: " + data.stream.viewers + "<br />";
|
||||
span_text = span_text + "</span>";
|
||||
$(jquery_selector).append(span_text);
|
||||
$(jquery_selector).append("<img src='" + data.stream.preview.medium + "' />")
|
||||
$('#streams-online').append("</article>");
|
||||
$('#stream-divider').show();
|
||||
} else {
|
||||
$.getJSON(data._links.channel+"?callback=?", function(data) {
|
||||
$('#streams-offline').append("<article class='uk-article' id='" + data.name + "'>");
|
||||
$('#'+data.name).append("<a href='"+data.url+"'><h4>" + data.display_name + "</h4></a>");
|
||||
//$('#'+data.name).append("<img src='" + data.logo + "' style='float: right;' width='62' height='62' /><br />");
|
||||
$('#'+data.name).append("<p class='uk-article-meta'><strong>Offline</strong></p>");
|
||||
$('#streams-offline').append("</div>");
|
||||
});
|
||||
}
|
||||
if (data.stream) {
|
||||
var $a = $("<a href='"+data.stream.channel.url+"'></a>");
|
||||
var $strm = $("<div class='dn-streamer uk-text-success uk-panel uk-panel-box' id='"+data.stream.channel.name+"'></div>");
|
||||
|
||||
$strm.append("<p class='uk-text-bold'>" + data.stream.channel.display_name + "</p>");
|
||||
$strm.append("<img src='" + data.stream.preview.small + "' />");
|
||||
$strm.append("<p><i class='uk-icon-male'></i> "+data.stream.viewers+"</p>");
|
||||
|
||||
$a.append($strm);
|
||||
$("#streams").prepend($a);
|
||||
|
||||
} else {
|
||||
$.getJSON(data._links.channel+"?callback=?", function(data) {
|
||||
var $a = $("<a href='"+data.url+"'></a>");
|
||||
var $strm = $("<div class='dn-streamer-offline uk-text-success uk-panel uk-panel-box' id='"+data.name+"'></div>");
|
||||
|
||||
$strm.append("<p class='uk-text-bold'>" + data.display_name + "</p>");
|
||||
$strm.append("<img src='" + data.logo + "' />");
|
||||
$strm.append("<p class='dn-offline'>Offline</p>");
|
||||
|
||||
$a.append($strm);
|
||||
$("#streams").append($a);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
{% endcache %}
|
||||
|
||||
|
||||
$(".dn-streamer, .dn-streamer-offline").on({
|
||||
mouseover: function() {
|
||||
$(this).addClass('dn-streamer-hover');
|
||||
},
|
||||
mouseleave: function() {
|
||||
$(this).removeClass('dn-streamer-hover');
|
||||
}
|
||||
}, "div");
|
||||
|
||||
// Localize the events
|
||||
$('.date').each( function( index ) {
|
||||
var d = new Date($(this).text());
|
||||
$(this).text( d.toLocaleDateString() + ' @ ' + d.toLocaleTimeString() );
|
||||
});
|
||||
|
||||
// About-us toggle
|
||||
$('#more,#less').click(function() {
|
||||
$('#more').toggle();
|
||||
$('#less').toggle();
|
||||
$('#about-us-more').toggle();
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
@ -10,6 +10,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
|
||||
<!-- CSS includes -->
|
||||
<!--<link rel="stylesheet" href="{{ url_for('static', filename='css/uikit.min.css') }}" />-->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/uikit.gradient.min.css') }}" />
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/app.css') }}" />
|
||||
|
||||
@ -22,36 +23,18 @@
|
||||
<nav class="uk-navbar uk-navbar-attached" data-uk-navbar>
|
||||
<a href="#offcanvas" class="uk-navbar-brand uk-hidden-large" data-uk-offcanvas><img src="{{ url_for('static', filename='img/navlogo.png') }}" /><i class="uk-icon-double-angle-down"></i></a>
|
||||
<a href="" class="uk-navbar-brand uk-visible-large" data-uk-offcanvas><img src="{{ url_for('static', filename='img/navlogo.png') }}" /></a>
|
||||
{# /* In header drop-down navigation, possibly reenable as static "you are here" marker */
|
||||
<ul class="uk-navbar-nav">
|
||||
<li data-uk-dropdown="" class="uk-parent">
|
||||
<a href="{{ url_for('main') }}"><i class="uk-icon-home"></i> Home</a>
|
||||
<div class="uk-dropdown uk-dropdown-navbar">
|
||||
<ul class="uk-nav uk-nav-navbar">
|
||||
<li><a href="http://board.dotanoobs.com">Board</a></li>
|
||||
<li><a href="{{ url_for('teamspeak') }}">TeamSpeak</a></li>
|
||||
<li class="uk-nav-header">Doobs</li>
|
||||
<li><a href="{{ url_for('doobs_stuff.list_events') }}">Events</a></li>
|
||||
<li><a href="{{ url_for('doobs_stuff.ladder') }}">Ladder</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
#}
|
||||
<!-- Check if user is logged in -->
|
||||
{% if g.user %}
|
||||
<ul class="uk-navbar-nav uk-navbar-flip">
|
||||
<li data-uk-dropdown="" class="uk-parent">
|
||||
<a href="#"><img class="uk-responsive-height" src="{{ g.user.avatar
|
||||
}}" /> {{ g.user.nickname }} </a>
|
||||
<a href="#"><img class="uk-responsive-height" src="{{ g.user.avatar }}" /> {{ g.user.nickname }} </a>
|
||||
<div class="uk-dropdown uk-dropdown-navbar">
|
||||
<ul class="uk-nav uk-nav-navbar">
|
||||
{#
|
||||
<li><a href="{{ url_for('doobs_stuff.doob_summary', playerid=g.doob._id) }}">Profile</a></li>
|
||||
<li><a href="{{ url_for('doobs_stuff.doob_random', playerid=g.doob._id) }}">A-Z Challenge</a></li>
|
||||
<!--<li class="uk-disabled"><a href="">Recent Events</a></li>-->
|
||||
<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>
|
||||
<li class="uk-nav-divider"></li>
|
||||
#}
|
||||
<li><a href="{{ url_for('user_settings', userid=g.user.id) }}">Settings</a></li>
|
||||
<li><a href="{{ url_for('logout') }}">Logout</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -65,10 +48,10 @@
|
||||
<!-- Flash Error Messages -->
|
||||
{% with messages = get_flashed_messages() %}
|
||||
{% if messages %}
|
||||
<ul class="flashes">
|
||||
<ul class="flashes uk-width-1-3 uk-container-center">
|
||||
<a href="" class="uk-alert-close uk-close"></a>
|
||||
{% for message in messages %}
|
||||
<li class="uk-alert uk-alert-danger">{{ category }}:{{ message }}</li>
|
||||
<li class="uk-alert uk-alert-danger">{{ message }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
@ -79,12 +62,12 @@
|
||||
<!-- Big top logo -->
|
||||
<div class="uk-width-1-1"><img class="uk-align-center" id="biglogo" src="{{ url_for('static', filename='img/biglogo.png') }}"></div>
|
||||
<!-- Side navigation -->
|
||||
<div class="uk-visible-large uk-width-1-5 uk-panel uk-panel-box">
|
||||
<div class="uk-visible-large uk-width-1-5 uk-panel">
|
||||
{% if g.doob%}
|
||||
<h3 class="uk-panel-title">{{ g.doob.name }}</h3>
|
||||
<hr class="uk-nav-divider" />
|
||||
{% endif %}
|
||||
<ul class="uk-nav uk-nav-side">
|
||||
<ul class="uk-nav uk-nav-side uk-text-right uk-nav-parent-icon" data-uk-nav>
|
||||
{% include 'sidenav.html' %}
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -4,29 +4,38 @@
|
||||
|
||||
{% block content %}
|
||||
<div class="uk-grid" data-uk-grid-margin>
|
||||
<div class="uk-width-1-1 uk-panel">
|
||||
<img class="uk-align-center" src="{{ user.avatar }}" />
|
||||
<h2 class="uk-panel-title uk-text-center">Profile for {{ user.nickname }}</h2>
|
||||
<div class="uk-width-2-3">
|
||||
<h2 class="uk-float-left"><img class="" src="{{ user.avatar }}" /> {{ user.nickname }}</h2>
|
||||
</div>
|
||||
<div class="uk-width-1-3 uk-text-center">
|
||||
<a href="http://steamcommunity.com/profiles/{{ user.steam_id | safe }}">Steam</a> |
|
||||
<a href="http://board.dotanoobs.com/?page=profile&id={{ user.id | safe }}">Forum Profile</a> |
|
||||
<a href="http://dotabuff.com/search?q={{ user.steam_id }}">Dotabuff</a>
|
||||
</div>
|
||||
<!--Main content area -->
|
||||
<div class="uk-width-large-2-3 uk-width-medium-1-1 uk-panel">
|
||||
<div class="uk-panel">
|
||||
main content area
|
||||
</div>
|
||||
{% if user.bio_text == None %}
|
||||
<em class="uk-text-danger">This user's profile bio is empty!</em>
|
||||
{% else %}
|
||||
<em class="uk-text-bold">{{ user.bio_text }}</em>
|
||||
{% endif %}
|
||||
{% if user.id == g.user.id %} <a href="{{ url_for('user_settings')}}"><i class="uk-icon-edit"></i></a>{% endif %}
|
||||
</div>
|
||||
<!-- Side bar -->
|
||||
<div class="uk-width-large-1-3 uk-width-medium-1-1 uk-panel uk-panel-box">
|
||||
<ul>
|
||||
<li>Points [value]</li>
|
||||
<li><a href="http://board.dotanoobs.com/?page=profile&id={{ user.id | safe }}">Forum Profile</a>
|
||||
<li>Last seen on TeamSpeak: [value]<li>
|
||||
</ul>
|
||||
<hr class="uk-panel-divider" />
|
||||
<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">
|
||||
Randomstats
|
||||
<span>Current Hero</span>
|
||||
Heroimg
|
||||
<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">
|
||||
<li>Points: <span id='points_total'>0</span></li>
|
||||
<li>Last Seen: <span id='date'></span></li>
|
||||
<li>Heroes Randomed: <span id='rands'>{{ user.random_heroes.completed | length }}</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
41
templates/settings.html
Normal file
41
templates/settings.html
Normal file
@ -0,0 +1,41 @@
|
||||
{% extends "layout.html" %}
|
||||
|
||||
{% block title %}Settings for {{ g.user.nickname }} - DotaNoobs {% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="uk-grid" data-uk-grid-margin>
|
||||
<div class="uk-width-2-3">
|
||||
<h2 class="uk-float-left"><img class="" src="{{ user.avatar }}" /> {{ user.nickname }}</h2>
|
||||
</div>
|
||||
<div class="uk-width-1-3 uk-text-center">
|
||||
</div>
|
||||
<!--Main content area -->
|
||||
<div class="uk-width-large-2-3 uk-width-medium-1-1 uk-panel">
|
||||
<form class="uk-form uk-form-width-large" action="" method="post" name="settings">
|
||||
{{ form.hidden_tag() }}
|
||||
<fieldset data-uk-margin>
|
||||
<legend>Settings</legend>
|
||||
<div class="uk-form-row">
|
||||
<ul class="uk-list">
|
||||
<li><label class="uk-form-label"> {{ form.public }} Public Profile</label></li>
|
||||
<li><label class="uk-form-label"><input type="checkbox" disabled> Show Big Logo</label></li>
|
||||
<li><label class="uk-form-label"><input type="checkbox" disabled> Nonexistant Setting</label></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="uk-form-row">
|
||||
<label class="uk-form-label">Twitch.tv Username:</label> <br/>
|
||||
{{ form.twitch(placeholder="e.g. shaneomad") }}
|
||||
</div>
|
||||
<div class="uk-form-row">
|
||||
<label class="uk-form-label">Biography text:</label><br/>
|
||||
{{ form.bio_text(rows=14, class='uk-width-1-1', data=g.user.bio_text, placedholder='What you place here is displayed in your profile when other users view it.') }}
|
||||
</div>
|
||||
<div class="uk-form-controls uk-margin-top">
|
||||
<button class="uk-button uk-button-success" type="submit">Save</button>
|
||||
<a class="uk-button" href="{{ url_for('user_profile', userid=g.user.id) }}">Cancel</a>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -2,13 +2,19 @@
|
||||
('index', 'Home'),
|
||||
('friends', 'Friends'),
|
||||
('list_events', 'Events'),
|
||||
('community', 'Community'),
|
||||
('ladder', 'Ladder'),
|
||||
('teamspeak', 'TS3 Stats'),
|
||||
] %}
|
||||
<li{% if endpoint == request.endpoint %} class='uk-active' {% endif %}>
|
||||
<a href="{{ url_for(endpoint) }}">{{ title }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
<li class="uk-parent">
|
||||
<a href="#">Stream Stats</a>
|
||||
<ul class="uk-nav-sub">
|
||||
<li><a href="http://potatr.dotanoobs.com">Potato_Bot</a></li>
|
||||
<li><a href="http://potatr.dotanoobs.com">Cider_Bot</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="uk-nav-divider"></li>
|
||||
<li class="uk-nav-header">Social</li>
|
||||
<li><a href="http://board.dotanoobs.com"><i class="uk-icon-group"> Board</i></a></li>
|
||||
@ -20,6 +26,6 @@
|
||||
<li><a href="{{ url_for('login') }}"><i class="uk-icon-cog"> Register</i></a></li>
|
||||
{% else %}
|
||||
<li {% if request.endpoint == 'user_profile' %} class='uk-active' {% endif %}><a href="{{ url_for('user_profile', userid=g.user.id) }}"><i class="uk-icon-home"> Profile</i></a></li>
|
||||
<li><a href="{{ url_for('user_profile', userid=g.user.id) }}"><i class="uk-icon-cog"> Settings</i></a></li>
|
||||
<li><a href="{{ url_for('user_settings', userid=g.user.id) }}"><i class="uk-icon-cog"> Settings</i></a></li>
|
||||
<li><a href="{{ url_for('logout') }}"><i class="uk-icon-off"> Logout</i></a></li>
|
||||
{% endif %}
|
||||
|
@ -26,7 +26,7 @@
|
||||
<h3 class="uk-text-bold uk-text-center">Current Status</h3>
|
||||
<a class="uk-button uk-button-success" href="ts3server://voice.dotanoobs.com">Connect</a>
|
||||
<a class="uk-button uk-button-primary" href="http://www.teamspeak.com/download">Download</a>
|
||||
<h5>Server: voice.dotanoobs.com</h5>
|
||||
<h5><strong>Server: voice.dotanoobs.com</strong></h5>
|
||||
<div class="uk-panel uk-text-left">
|
||||
{{ ts3_viewer() | safe }}
|
||||
</div>
|
||||
|
69
utils.py
69
utils.py
@ -1,6 +1,10 @@
|
||||
import requests
|
||||
import re
|
||||
from time import strptime, strftime, gmtime
|
||||
from bs4 import BeautifulSoup
|
||||
from itertools import product
|
||||
from os import path, makedirs
|
||||
|
||||
from calendar import timegm
|
||||
from app import app, cache
|
||||
from teamspeak import create_teamspeak_viewer, getTeamspeakWindow, ISO3166_MAPPING
|
||||
@ -10,13 +14,36 @@ def get_steam_userinfo(steam_id):
|
||||
'key': app.config['DOTA2_API_KEY'],
|
||||
'steamids': steam_id
|
||||
}
|
||||
data = requests.get('http://api.steampowered.com/ISteamUser/' \
|
||||
'GetPlayerSummaries/v0001/', params=options).json()
|
||||
data = requests.get('http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0001/', params=options).json()
|
||||
return data['response']['players']['player'][0] or {}
|
||||
|
||||
def get_api_hero_data():
|
||||
data = requests.get("https://api.steampowered.com/IEconDOTA2_570/GetHeroes/v0001/?key="+app.config['DOTA2_API_KEY']+"&language=en_us").json()
|
||||
return data
|
||||
|
||||
API_DATA = get_api_hero_data()
|
||||
|
||||
def complete_hero_data(key, value):
|
||||
# Possible keys are id, localized_name and name
|
||||
for hero_data in API_DATA['result']['heroes']:
|
||||
if hero_data[key] == value: return hero_data
|
||||
|
||||
def get_hero_data_by_id(hero_id):
|
||||
return API_DATA['result']['heroes'][hero_id-1]
|
||||
|
||||
def parse_valve_heropedia():
|
||||
data = requests.get('http://www.dota2.com/heroes/')
|
||||
soup = BeautifulSoup(data.text)
|
||||
taverns = []
|
||||
tavern_names = [' '.join(entry) for entry in product(('Radiant', 'Dire'), ('Strength', 'Agility', 'Intelligence'))]
|
||||
for tavern_name, tavern in zip(tavern_names, soup.find_all(class_=re.compile('^heroCol'))):
|
||||
img_base = lambda tag: tag.name == 'img' and 'base' in tag.get('id')
|
||||
taverns.append((tavern_name, [complete_hero_data('name', 'npc_dota_hero_%s' % tag['id'].replace('base_', '')) for tag in tavern.find_all(img_base)]))
|
||||
return taverns
|
||||
|
||||
# For Templates
|
||||
@app.template_filter('shorten')
|
||||
def shorten_filter(s, num_words=20):
|
||||
def shorten_filter(s, num_words=40):
|
||||
space_iter = re.finditer('\s+', s)
|
||||
output = u''
|
||||
while num_words > 0:
|
||||
@ -30,6 +57,7 @@ def shorten_filter(s, num_words=20):
|
||||
|
||||
@app.context_processor
|
||||
def utility_processor():
|
||||
''' For Teamspeak '''
|
||||
@cache.memoize(60*5)
|
||||
def ts3_viewer():
|
||||
html = create_teamspeak_viewer()[0]
|
||||
@ -63,6 +91,38 @@ def utility_processor():
|
||||
for key, name in ISO3166_MAPPING.iteritems():
|
||||
mapping[key.lower()] = ' '.join([word.capitalize() for word in name.split(' ')])
|
||||
return mapping
|
||||
''' Dota2 info '''
|
||||
def total_hero_pool():
|
||||
return len(API_DATA['result']['heroes'])
|
||||
def hero_image_large(hero_data):
|
||||
if type(hero_data) is unicode:
|
||||
stripped_name = hero_data.replace('npc_dota_hero_', '')
|
||||
else:
|
||||
stripped_name = hero_data['name'].replace('npc_dota_hero_', '')
|
||||
img_file = path.join(app.config['HERO_IMAGE_PATH'], stripped_name + '.png')
|
||||
img_src = path.join(app.root_path, app.static_folder, img_file)
|
||||
if not path.exists(img_src):
|
||||
i = requests.get('http://media.steampowered.com/apps/dota2/images/heroes/{}_hphover.png'.format(stripped_name)).content
|
||||
if not path.exists(path.split(img_src)[0]):
|
||||
makedirs(path.split(img_src)[0])
|
||||
with open(img_src, 'wb') as img:
|
||||
img.write(i)
|
||||
return img_file
|
||||
def hero_image_small(hero_data):
|
||||
if type(hero_data) is unicode:
|
||||
stripped_name = hero_data.replace('npc_dota_hero_', '')
|
||||
else:
|
||||
stripped_name = hero_data['name'].replace('npc_dota_hero_', '')
|
||||
img_file = path.join(app.config['HERO_IMAGE_PATH'], stripped_name + '_small.png')
|
||||
img_src = path.join(app.root_path, app.static_folder, img_file)
|
||||
if not path.exists(img_src):
|
||||
i = requests.get('http://media.steampowered.com/apps/dota2/images/heroes/{}_sb.png'.format(stripped_name)).content
|
||||
if not path.exists(path.split(img_src)[0]):
|
||||
makedirs(path.split(img_src)[0])
|
||||
with open(img_src, 'wb') as img:
|
||||
img.write(i)
|
||||
return img_file
|
||||
''' Misc '''
|
||||
def timestamp_to_js_date(timestamp):
|
||||
return strftime('%B %d, %Y %H:%M:%S UTC', gmtime(timestamp))
|
||||
def js_date_to_timestamp(date):
|
||||
@ -70,4 +130,5 @@ def utility_processor():
|
||||
return dict(ts3_viewer=ts3_viewer, ts3_current_clients=ts3_current_clients, get_teamspeak_window=get_teamspeak_window, \
|
||||
ts3_active_clients=ts3_active_clients, timestamp_to_js_date=timestamp_to_js_date, js_date_to_timestamp=js_date_to_timestamp, \
|
||||
num_unique_clients_by_country=num_unique_clients_by_country, country_abbreviation_mapping=country_abbreviation_mapping, \
|
||||
ts3_countries_active=ts3_countries_active)
|
||||
ts3_countries_active=ts3_countries_active, hero_image_large=hero_image_large, hero_image_small=hero_image_small, \
|
||||
heropedia=parse_valve_heropedia, total_hero_pool=total_hero_pool)
|
||||
|
99
views.py
99
views.py
@ -1,18 +1,22 @@
|
||||
from flask import render_template, flash, redirect, g, request, url_for, session
|
||||
from datetime import datetime
|
||||
|
||||
from app import app, db, oid, cache
|
||||
from models import User
|
||||
from utils import get_steam_userinfo
|
||||
from board import latest_news
|
||||
from forms import SettingsForm
|
||||
|
||||
@app.before_request
|
||||
def before_request():
|
||||
g.user = None
|
||||
if 'user_id' in session:
|
||||
g.user = User.query.get(session['user_id'])
|
||||
g.user = User.query.get(session['user_id'])
|
||||
if g.user:
|
||||
g.user.last_seen = datetime.utcnow()
|
||||
db.session.commit()
|
||||
|
||||
@app.route('/')
|
||||
@app.route('/main')
|
||||
def index():
|
||||
return render_template("index.html", latest_news=latest_news())
|
||||
|
||||
@ -32,7 +36,7 @@ def create_or_login(resp):
|
||||
g.user.avatar = steamdata['avatar']
|
||||
db.session.commit()
|
||||
session['user_id'] = g.user.id
|
||||
flash("You are logged in as {}".format(g.user.nickname))
|
||||
flash("You are logged in as {}".format(g.user.nickname))
|
||||
return redirect(oid.get_next_url())
|
||||
|
||||
@app.route('/logout')
|
||||
@ -42,69 +46,56 @@ def logout():
|
||||
|
||||
|
||||
### TEMPORARY ###
|
||||
@app.route('/teamspeak')
|
||||
def teamspeak():
|
||||
return render_template('teamspeak.html')
|
||||
@app.route('/list_events')
|
||||
def list_events():
|
||||
return "Events list!"
|
||||
@app.route('/friends')
|
||||
def friends():
|
||||
return render_template('friends.html')
|
||||
@app.route('/community')
|
||||
def community():
|
||||
return "Community!"
|
||||
@app.route('/ladder')
|
||||
def ladder():
|
||||
return "Ladder!"
|
||||
### ###
|
||||
|
||||
#From league/doobs_blueprint.py
|
||||
@app.route('/profile/<int:userid>')
|
||||
|
||||
# Teamspeak statistics page
|
||||
@app.route('/teamspeak')
|
||||
def teamspeak():
|
||||
return render_template('teamspeak.html')
|
||||
|
||||
# Friends of doobs page
|
||||
@app.route('/friends')
|
||||
def friends():
|
||||
return render_template('friends.html')
|
||||
|
||||
# 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)
|
||||
|
||||
'''
|
||||
from flask import render_template, flash, redirect, g, request, url_for
|
||||
from app import app, oid
|
||||
# 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)
|
||||
|
||||
@app.route('/login')
|
||||
@oid.loginhandler
|
||||
def login():
|
||||
if g.user is not None:
|
||||
return redirect(oid.get_next_url())
|
||||
return oid.try_login('http://www.steamcommunity.com/openid')
|
||||
|
||||
@oid.after_login
|
||||
def check_login(resp):
|
||||
match = app.config['STEAM_ID_RE'].search(resp.identity_url)
|
||||
return "none"
|
||||
|
||||
@app.route('/')
|
||||
def main():
|
||||
return render_template('main.html')
|
||||
|
||||
@app.route('/community')
|
||||
def community():
|
||||
return render_template('community.html', latest_posts=latest_posts())
|
||||
|
||||
@app.route('/friends')
|
||||
def friends():
|
||||
return render_template('friends.html')
|
||||
|
||||
@app.route('/teamspeak')
|
||||
def teamspeak():
|
||||
return render_template('teamspeak.html')
|
||||
|
||||
@app.route('/events')
|
||||
def list_events():
|
||||
return render_template('events.html')
|
||||
|
||||
@app.route('/events/<int:id>')
|
||||
def event_summary(id):
|
||||
return render_template('events.html')
|
||||
|
||||
@app.route('/ladder')
|
||||
def ladder():
|
||||
return render_template('ladder.html')
|
||||
'''
|
||||
# User settings page
|
||||
@app.route('/settings', methods=['POST', 'GET'])
|
||||
def user_settings():
|
||||
user = User.query.filter_by(id=g.user.id).first_or_404()
|
||||
form = SettingsForm(obj=user)
|
||||
if form.validate_on_submit():
|
||||
g.user.bio_text = form.bio_text.data
|
||||
g.user.twitch = form.twitch.data
|
||||
db.session.commit()
|
||||
flash('Settings updated!')
|
||||
return render_template('profile.html', user=g.user)
|
||||
else:
|
||||
form.populate_obj(user)
|
||||
return render_template('settings.html', user=g.user, form=form)
|
||||
|
Loading…
x
Reference in New Issue
Block a user