From 3160967fa8654770c6ecad3a376dc98357cea323 Mon Sep 17 00:00:00 2001 From: binaryatrocity Date: Sun, 22 Jun 2014 20:11:42 -0500 Subject: [PATCH] Update before moving GIT heirarchy --- __init__.py | 220 +------------------------------------- board.py | 24 ++++- forms.py | 20 +++- models.py | 221 +++++++++++++++++++++++++++++++++++---- static/css/app.css | 32 ++++-- teamspeak.py | 26 ++++- templates/friends.html | 66 +++++++----- templates/index.html | 59 +++++------ templates/layout.html | 46 +++++--- templates/profile.html | 29 +++-- templates/settings.html | 9 +- templates/sidenav.html | 17 +-- templates/teamspeak.html | 17 +-- utils.py | 27 +++-- views.py | 130 ++++++++++++++++++----- 15 files changed, 548 insertions(+), 395 deletions(-) diff --git a/__init__.py b/__init__.py index f7a4ffe..47413f6 100644 --- a/__init__.py +++ b/__init__.py @@ -9,222 +9,4 @@ db = SQLAlchemy(app) oid = OpenID(app) cache = Cache(app, config={'CACHE_TYPE': app.config['CACHE_TYPE']}) -from app import views - -''' -from flask import Flask, render_template -from flask.ext.mongoengine import MongoEngine -from flask.ext.openid import OpenID -from flask.ext.cache import Cache -import utils -import ts3 - -app = Flask(__name__) -app.config.from_object('config') - -#Setup mongo database -db = MongoEngine(app) - -#Setup OpenID and Caching -oid = OpenID(app) -cache = Cache(app, config={'CACHE_TYPE': app.config['CACHE_TYPE']}) - -from app import views -@app.route('/') -def inx(): - return render_template('main.html') - -##### INTO UTILS LATER ##### -RADIANT_TEAM = 2 -DIRE_TEAM = 3 -RADIANT_COLOR = 'b' -DIRE_COLOR = 'r' - -def get_hero_data(): - xhr = urllib2.build_opener().open(urllib2.Request("https://api.steampowered.com/IEconDOTA2_570/GETHeroes/v0001/?key="+DOTA2_API_KEY+"&language=en_us")) - data = json.load(xhr) - return data - -@app.context_processor -def utility_processor(): - @cache.memoize(60*5) - def ts3_viewer(): - try: - server = ts3.TS3Server(app.config['TS3_HOST'], app.config['TS3_PORT']) - server.login(app.config['TS3_USERNAME'], app.config['TS3_PASSWORD']) - server.use(1) - - serverinfo = server.send_command('serverinfo').data - channellist = server.send_command('channellist', opts=("limits", "flags", "voice", "icon")).data - clientlist = server.send_command('clientlist', opts=("away", "voice", "info", "icon", "groups", "country")).data - servergrouplist = server.send_command('servergrouplist').data - channelgrouplist = server.send_command('channelgrouplist').data - - soup = BeautifulSoup() - div_tag = soup.new_tag('div') - div_tag['class'] ='devmx-webviewer' - soup.append(div_tag) - - def construct_channels(parent_tag, cid): - num_clients = 0 - for channel in channellist: - if int(channel['pid']) == int(cid): - # Construct the channel - channel_tag = soup.new_tag('div') - channel_tag['class'] = 'tswv-channel' - # Channel image - image_tag = soup.new_tag('span') - image_tag['class'] = 'tswv-image tswv-image-right' - if int(channel['channel_flag_password']) == 1: - image_tag['class'] += ' tswv-channel-password-right' - if int(channel['channel_flag_default']) == 1: - image_tag['class'] += ' tswv-channel-home' - if int(channel['channel_needed_talk_power']) > 0: - image_tag['class'] += ' tswv-channel-moderated' - if int(channel['channel_icon_id']) != 0: - raise NotImplementedError - image_tag.append(' ') - channel_tag.append(image_tag) - # Status image - status_tag = soup.new_tag('span') - status_tag['class'] = 'tswv-image' - if int(channel['channel_flag_password']) == 1: - status_tag['class'] += ' tswv-channel-password' - elif int(channel['total_clients']) == int(channel['channel_maxclients']): - status_tag['class'] += ' tswv-channel-full' - else: - status_tag['class'] += ' tswv-channel-normal' - status_tag.append(' ') - channel_tag.append(status_tag) - # Label - label_tag = soup.new_tag('span') - label_tag['class'] = 'tswv-label' - label_tag.append(channel['channel_name']) - channel_tag.append(label_tag) - # Clients - channel_tag, channel_clients = construct_clients(channel_tag, channel['cid']) - # Recurse through sub-channels, collecting total number of clients as we go - channel_tag, sub_clients = construct_channels(channel_tag, channel['cid']) - channel_clients += sub_clients - # Only show non-empty channels - if channel_clients > 0: - parent_tag.append(channel_tag) - num_clients += channel_clients - return parent_tag, num_clients - - def construct_clients(parent_tag, cid): - num_clients = 0 - for client in clientlist: - if int(client['cid']) == int(cid): - # Skip ServerQuery clients - if int(client['client_type']) == 1: continue - num_clients += 1 - client_tag = soup.new_tag('div') - client_tag['class'] = 'tswv-client' - # Status image - status_tag = soup.new_tag('span') - status_tag['class'] = 'tswv-image' - if int(client['client_type']) == 1: - status_tag['class'] += ' tswv-client-query' - elif int(client['client_away']) == 1: - status_tag['class'] += " tswv-client-away" - elif int(client['client_input_muted']) == 1: - status_tag['class'] += " tswv-client-input-muted" - elif int(client['client_output_muted']) == 1: - status_tag['class'] += " tswv-client-output-muted" - elif int(client['client_input_hardware']) == 0: - status_tag['class'] += " tswv-client-input-muted-hardware" - elif int(client['client_output_hardware']) == 0: - status_tag['class'] += " tswv-client-output-muted-hardware" - elif (int(client['client_flag_talking']) == 1) and (int(client['client_is_channel_commander']) == 1): - status_tag['class'] += " tswv-client-channel-commander-talking" - elif int(client['client_is_channel_commander']) == 1: - status_tag['class'] += " tswv-client-channel-commander" - elif int(client['client_flag_talking']) == 1: - status_tag['class'] += " tswv-client-talking" - else: - status_tag['class'] += " tswv-client-normal" - status_tag.append(' ') - client_tag.append(status_tag) - # Country image - country_tag = soup.new_tag('span') - country_tag['class'] = 'tswv-image tswv-image-right' - country_tag['title'] = ' '.join([word.capitalize() for word in utils.ISO3166_MAPPING[client['client_country']].split(' ')]) - country_tag['style'] = 'background: url("%s") center center no-repeat;' % url_for('static', filename='img/ts3_viewer/countries/%s.png' % client['client_country'].lower()) - country_tag.append(' ') - client_tag.append(country_tag) - # Server group images - sgids = [int(sg) for sg in client['client_servergroups'].split(',')] - servergroups = [servergroup for servergroup in servergrouplist if int(servergroup['sgid']) in sgids] - servergroups.sort(key=operator.itemgetter('sortid')) - for servergroup in servergroups: - if not servergroup['iconid']: continue - img_fname = 'img/ts3_viewer/%s.png' % servergroup['iconid'] - if not os.path.exists(os.path.join(app.static_folder, img_fname)): - continue - image_tag = soup.new_tag('span') - image_tag['class'] = 'tswv-image tswv-image-right' - image_tag['title'] = servergroup['name'] - image_tag['style'] = 'background-image: url("%s")' % url_for('static', filename=img_fname) - image_tag.append(' ') - client_tag.append(image_tag) - # Check if client is in a moderated channel - channel = [channel for channel in channellist if int(channel['cid']) == int(client['cid'])][0] - if int(channel['channel_needed_talk_power']) > 0: - status_tag = soup.new_tag('span') - status_tag['class'] = 'tswv-image tswv-image-right' - if int(client['client_is_talker']) == 0: - status_tag['class'] += ' tswv-client-input-muted' - else: - status_tag['class'] += ' tswv-client-talkpower-granted' - status_tag.append(' ') - client_tag.append(status_tag) - # Label - label_tag = soup.new_tag('span') - label_tag['class'] = 'tswv-label' - label_tag.append(client['client_nickname']) - client_tag.append(label_tag) - parent_tag.append(client_tag) - return parent_tag, num_clients - div_tag, num_clients = construct_channels(div_tag, 0) - return soup.prettify() - except Exception as inst: - return "error: %s" % inst - def shorten_text(text, num_words=10): - text = utils.fix_bad_unicode(text) - space_iter = re.finditer('\s+', text) - output = u'' - while num_words > 0: - match = space_iter.next() - if not match: break - output = text[:match.end()] - num_words -= 1 - else: - output += '...' - return output - def num_unique_clients(teamspeak_data): - unique_clients = set() - for data in teamspeak_data: - unique_clients.update(data.clients) - return len(unique_clients) - def num_unique_clients_by_country(teamspeak_data): - unique_clients = {} - for data in teamspeak_data: - for client_id, client_data in data.clients.iteritems(): - unique_clients[client_id] = (client_data['country'] or 'Unknown').lower() - country = {} - for client_id, country_code in unique_clients.iteritems(): - country[country_code] = country.get(country_code, 0) + 1 - return country - def country_abbreviation_mapping(): - mapping = {} - for key, name in utils.ISO3166_MAPPING.iteritems(): - mapping[key.lower()] = ' '.join([word.capitalize() for word in name.split(' ')]) - return mapping - return dict(timestamp_to_js_date=utils.timestamp_to_js_date, ts3_viewer=ts3_viewer, shorten_text=shorten_text, getTeamspeakWindow=doob.getTeamspeakWindow, - num_unique_clients=num_unique_clients, - num_unique_clients_by_country=num_unique_clients_by_country, - country_abbreviation_mapping=country_abbreviation_mapping) - - - ''' +from app import views, models diff --git a/board.py b/board.py index e27e871..320c078 100644 --- a/board.py +++ b/board.py @@ -1,17 +1,31 @@ import os import re from time import strftime, gmtime +from hashlib import sha256 from peewee import * -from app import app, cache -db = MySQLDatabase(app.config['FORUM_NAME'], **{'passwd': app.config['FORUM_PASSWORD'], +from app import app, cache, db + +board_db = MySQLDatabase(app.config['FORUM_NAME'], **{'passwd': app.config['FORUM_PASSWORD'], 'host': app.config['FORUM_HOST'], 'user': app.config['FORUM_USERNAME']}) +def registerUserForumId(user, username, password): + try: + u = Users.filter(name=username).get() + hashpass = sha256(password+app.config['FORUM_SALT']+u.pss).hexdigest() + if hashpass == u.password: + user.forum_id = u.id + db.session.commit() + return {"forum_name":u.name, "forum_id":u.id} + except DoesNotExist: + pass + return False + @cache.memoize(60*5) def latest_news(num=3): latest_news = [] try: - db.connect() + board_db.connect() news_forum = Forums.get(fn.Lower(Forums.title) % '%news%') for thread in Threads.select().where( Threads.forum == news_forum.id).order_by(Threads.date.desc()).limit(num): @@ -32,7 +46,7 @@ def latest_news(num=3): except Exception as e: latest_news.append({'title':'Error with forum db', 'text':e, 'url':''}) finally: - db.close() + board_db.close() return latest_news class UnknownFieldType(object): @@ -40,7 +54,7 @@ class UnknownFieldType(object): class BaseModel(Model): class Meta: - database = db + database = board_db class Badges(BaseModel): color = IntegerField() diff --git a/forms.py b/forms.py index 7caaf92..a38f303 100644 --- a/forms.py +++ b/forms.py @@ -1,7 +1,23 @@ -from flask.ext.wtf import Form -from wtforms import TextField, BooleanField, TextAreaField +from flask_wtf import Form +from wtforms import TextField, BooleanField, TextAreaField, PasswordField, SelectField, IntegerField, DateTimeField, validators +from datetime import datetime class SettingsForm(Form): public = BooleanField('public', default=True) + logo = BooleanField('biglogo', default=True) twitch = TextField('twitch') bio_text = TextAreaField('bio_text') + +class EnableStatsForm(Form): + teamspeak_id = TextField('teamspeak_id') + forum_username = TextField('forum_username') + forum_password = PasswordField('forum_password') + +class EventForm(Form): + name = TextField('name', [validators.Required()]) + desc = TextAreaField('desc', [validators.Required()]) + type = SelectField(u'Event Type', choices=[('coaching', 'Coaching'), ('inhouse', 'In-House'), ('tournament', 'Tournament'), ('other', 'Other')]) + start_time = DateTimeField('start_time', format='%d.%m.%Y %H:%M') + end_time = DateTimeField('end_time', format='%d.%m.%Y %H:%M') + points = IntegerField('points', [validators.Required()]) + reward_threshold = IntegerField('reward_threshold') diff --git a/models.py b/models.py index c657dfb..3b214da 100644 --- a/models.py +++ b/models.py @@ -1,11 +1,23 @@ import simplejson as json +from datetime import datetime from random import choice from flask.ext.sqlalchemy import SQLAlchemy from sqlalchemy.ext.mutable import Mutable -from time import time -from app import db + +import board +from app import db, app from utils import parse_valve_heropedia, complete_hero_data +# Model independant get_or_create +def get_or_create_instance(session, model, **kwargs): + instance = session.query(model).filter_by(**kwargs).first() + if instance: + return instance + else: + instance = model(**kwargs) + session.add(instance) + return instance + # Get a little of that Mongoness back class Json(db.TypeDecorator): impl = db.Text @@ -20,7 +32,7 @@ class Json(db.TypeDecorator): value = json.loads(value) return value - +# Mongoness factor - phase 2 class MutableDict(Mutable, dict): @classmethod def coerce(cls, key, value): @@ -46,27 +58,51 @@ class MutableDict(Mutable, dict): self.update(self) - class User(db.Model): id = db.Column(db.Integer, primary_key=True) steam_id = db.Column(db.String(40), unique=True) + forum_id = db.Column(db.Integer) + teamspeak_id = db.Column(db.String(200), unique=True) + nickname = db.Column(db.String(80)) avatar = db.Column(db.String(255)) - random_heroes = db.Column(MutableDict.as_mutable(Json)) + 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)) - - @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 - rv.random_heroes = {'current':None, 'completed':[]} - bio_text = '' - db.session.add(rv) - return rv + random_heroes = db.Column(MutableDict.as_mutable(Json)) + + public = db.Column(db.Boolean) + logo = db.Column(db.Boolean) + + points_from_events = db.Column(db.Integer) + points_from_ts3 = db.Column(db.Integer) + points_from_forum = db.Column(db.Integer) + 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)) + last_post_reward = db.Column(db.Integer) + + + @classmethod + def get_or_create(self, steam_id): + return get_or_create_instance(db.session, User, steam_id=steam_id) + + def __init__(self, steam_id): + self.steam_id = steam_id + self.random_heroes = {'current':None, 'completed':[]} + self.created = datetime.utcnow() + self.last_seen = datetime.utcnow() + self.bio_text = None + self.points_from_events = 0 + self.points_from_ts3 = 0 + self.points_from_forum = 0 + self.admin = False + self.public = True + self.biglogo = True @property def random_hero(self): @@ -103,14 +139,161 @@ class User(db.Model): 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: + duration = (self.ts3_endtime - self.ts3_rewardtime) / 60.0 + if duration > reward_threshold: + self.ts3_rewardtime = datetime.utcnow() + self.points_from_ts3 += 1 + else: + self.ts3_rewardtime = datetime.utcnow() + self.last_seen = datetime.utcnow() + print self.ts3_starttime, self.ts3_endtime, self.ts3_rewardtime + db.session.commit(); + + def finalize_connection(self): + self.ts3_connections.append({'starttime': self.ts3_starttime, 'endtime': self.ts3_endtime}) + self.ts3_startime = None + self.ts3_endtime = None + db.session.commit(); + + def update_forum_posts(self, reward_threshold=5): + if self.forum_id: + 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 + if num_points > 0: + self.points_from_forum += num_points + self.last_post_reward += num_points * reward_threshold + else: + # Initialize if this is the first reward + self.last_post_reward = posts + db.session.commit() + + @property + def is_active(self): + return self.ts3_starttime and True or False + def __repr__(self): - return ''.format(self.nickname) + return ''.format(self.id) class TeamspeakData(db.Model): id = db.Column(db.Integer, primary_key=True) - time = db.Column(db.Float()) + time = db.Column(db.DateTime()) clients = db.Column(Json()) def __init__(self, clientlist): - self.time = time() + self.time = datetime.utcnow() self.clients = clientlist + +class Event(db.Model): + id = db.Column(db.Integer, primary_key=True) + name = db.Column(db.String(200)) + desc = db.Column(db.String(4096)) + type = db.Column(db.String(20)) + + start_time = db.Column(db.DateTime) + end_time = db.Column(db.DateTime) + points = db.Column(db.Integer) + reward_threshold = db.Column(db.Integer) + + total_subchans = db.Column(db.Integer) + channels = db.Column(MutableDict.as_mutable(Json)) + participants = db.Column(MutableDict.as_mutable(Json)) + + def __init__(self, id): + self.channels = {'event_cid':None, 'cids':[]} + + @classmethod + def get_or_create(self, event_id): + return get_or_create_instance(db.session, Event, id=event_id) + + @property + def cids(self): + return self.channels['cids'] + + @property + def event_cid(self): + return self.channels['event_cid'] + + @property + def channel_ids(self): + cids = self.channels['cids'] + if self.channels['event_cid']: + cids.append(self.channels['event_cid']) + return cids + + def create_channels(self): + import ts3 + server = ts3.TS3Server(app.config['TS3_HOST'], app.config['TS3_PORT']) + server.login(app.config['TS3_USERNAME'], app.config['TS3_PASSWORD']) + server.use(1) + # Create the parent channel + if not self.event_cid: + # Find the LFG channel and place this one after + response = server.send_command('channelfind', keys={'pattern': 'Looking for Group'}) + if response.is_successful: + cid = response.data[0]['cid'] + response = server.send_command('channelcreate', keys={'channel_name':self.name.encode('utf-8'), 'channel_flag_semi_permanent':'1', 'channel_order':cid}) + if response.is_successful: + self.channels['event_cid'] = response.data[0]['cid'] + # Create the subchannels + if not self.cids: + cids = [] + keys = {'channel_name':'Event Room #{}'.format(len(self.cids) + 1), 'channel_flag_semi_permanent':'1', 'cpid':self.event_cid.encode('utf-8')} + response = server.send_command('channelcreate', keys=keys) + if response.is_successful: + parent_cid = response.data[0]['cid'] + cids.append(parent_cid) + else: + raise UserWarning("channelcreate failed") + response = server.send_command('channelcreate', keys={'channel_name':'Radiant Team', 'channel_flag_semi_permanent':'1', 'cpid':parent_cid}) + if response.is_successful: + cids.append(response.data[0]['cid']) + response = server.send_command('channelcreate', keys={'channel_name':'Dire Team', 'channel_flag_semi_permanent':'1', 'cpid':parent_cid}) + if response.is_successful: + cids.append(response.data[0]['cid']) + response = server.send_command('channelcreate', keys={'channel_name':'Spectators', 'channel_flag_semi_permanent':'1', 'cpid':parent_cid}) + if response.is_successful: + cids.append(response.data[0]['cid']) + self.channels['cids'] = cids + db.session.commit() + + def remove_channels(self): + import ts3 + server = ts3.TS3Server(app.config['TS3_HOST'], app.config['TS3_PORT']) + server.login(app.config['TS3_USERNAME'], app.config['TS3_PASSWORD']) + server.use(1) + response = server.send_command('channeldelete', keys={'cid':self.event_cid.encode('utf-8'), 'force':'1'}) + if response.is_successful: + self.channels = {'event_cid': None, 'cids':[]} + db.session.commit() + + @property + def active(self): + current_time = datetime.utcnow() + return self.start_time < current_time and current_time < self.end_time + + @property + def expired(self): + current_time = datetime.utcnow() + return self.end_time < curent_time + + def add_participant(self, user): + entry = self.participants.setdefault(user, {'start_time': datetime.utcnow() }) + entry['end_time'] = datetime.utcnow() + if 'points' not in entry and (entry['end_time'] - entry['start_time']) > self.reward_threshold: + user.points_from_events += self.points + entry['points'] = self.points + db.session.commit() + + @property + def participants(self): + return tuple(self.participants) + + def __repr__(self): + return ''.format(self.id) diff --git a/static/css/app.css b/static/css/app.css index 22bbd52..1d858d4 100644 --- a/static/css/app.css +++ b/static/css/app.css @@ -50,9 +50,6 @@ footer { padding-bottom:80px; } -#streams-online > .uk-article > a > h4 { - margin:0px; -} #tsviewer > .uk-modal-dialog { max-height: 80%; overflow-y: scroll; @@ -63,16 +60,21 @@ footer { } .dn-streamer, .dn-streamer-offline { display: inline-block; - width: 110px; - padding: 5px; - margin: 5px; + width: 105px; + padding: 2px; + margin: 2px; +} + +#streams p.uk-text-bold { + font-size: 12px; } + .dn-streamer-offline > img { height:50px; } .dn-streamer-hover { - background:red; + background:#CACACA; } .dn-hero-icon { @@ -80,3 +82,19 @@ footer { padding:4px; margin:2px; } + +#streams { + padding:10px; +} + +#events_small > dl.uk-description-list-line > dt, #events_large > dl.uk-description-list-line > dt { + border-top: none; +} + +#events_small .uk-badge, #events_large .uk-badge { + float:right; +} + +#profile_links > a { + font-size:14px; +} diff --git a/teamspeak.py b/teamspeak.py index 6c2c564..4f940eb 100644 --- a/teamspeak.py +++ b/teamspeak.py @@ -1,19 +1,35 @@ +from flask import url_for + import operator import os import ts3 -import time import requests +from datetime import datetime, timedelta from xml.etree import ElementTree -from flask import url_for from bs4 import BeautifulSoup -from app import app +from app import app, db -def getTeamspeakWindow(window=605800): - current_time = time.time() +def getTeamspeakWindow(window=timedelta(weeks=1)): + current_time = datetime.utcnow() from models import TeamspeakData return TeamspeakData.query.filter(TeamspeakData.time < current_time, TeamspeakData.time > current_time-window).order_by(TeamspeakData.time).all() +def registerUserTeamspeakId(user, tsid): + server = ts3.TS3Server(app.config['TS3_HOST'], app.config['TS3_PORT']) + server.login(app.config['TS3_USERNAME'], app.config['TS3_PASSWORD']) + server.use(1) + + response = server.send_command('clientdbfind', {'pattern':tsid.encode('utf-8')}, ('uid',)) + if response.is_successful: + cdbid = response.data[0]['cldbid'] + user.teamspeak_id = tsid + sgid = [entry['sgid'] for entry in server.send_command('servergrouplist').data if entry['name'] == 'Normal' and entry['type'] == '1'][0] + server.send_command('servergroupaddclient', {'sgid': sgid, 'cldbid': cdbid}) + db.session.commit() + return True + return False + def create_teamspeak_viewer(): try: server = ts3.TS3Server(app.config['TS3_HOST'], app.config['TS3_PORT']) diff --git a/templates/friends.html b/templates/friends.html index 16b9aa6..bd350ea 100644 --- a/templates/friends.html +++ b/templates/friends.html @@ -16,7 +16,7 @@

Internet Friendlies:

-

DotA related websites worth the occasional visit. We know they are no DotaNoobs, but we set a pretty high quality standard.

+

DotA related websites worth the occasional visit. We know they are no DotaNoobs, but we set a pretty high quality standard around here.

Streams We Like

-
    -
- -
    +
@@ -38,34 +35,49 @@ {% block pagescripts %} {% endblock %} diff --git a/templates/index.html b/templates/index.html index 49a7f21..7e11315 100644 --- a/templates/index.html +++ b/templates/index.html @@ -5,32 +5,16 @@ {% block title %}Dota Noobs{% endblock %} {% block content %} -{#{% cache 60*5 %}#} +{% cache 60*5 %} {% set teamspeak_data = get_teamspeak_window() %} +{% set latest_news = get_latest_news() %}
-
-

Events

- {# - {% if active_event %} - - {% endif %} - {% if upcoming_event %} - - {% else %} - No events planned for the near future. Suggest one on the forum! - {% endif %} - #} - No events planned for the near future. Suggest one on the forum! + +
+ {% include "events_widget.html" %}
-
+ +
Users

Teamspeak

@@ -57,11 +41,15 @@
-
+
+ {% include "events_widget.html" %} +
+ +
-
-

News and Announcements

+
+

News and Announcements

{% for news in latest_news %} {% endfor %}
+
-{#{% endcache %}#} +{% endcache %} {% endblock %} {% block pagescripts %} {% endblock %} diff --git a/templates/layout.html b/templates/layout.html index 05b2a73..96545dd 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -10,13 +10,14 @@ - - + - + + + @@ -33,25 +34,27 @@
  • Profile
  • A-Z Challenge
  • Latest Posts
  • + {% if g.user.admin %} +
  • Add Event
  • + {% endif %}
  • -
  • Settings
  • +
  • Settings
  • Logout
  • {% else %} - + {% endif %}
    DotaNoobs
    - {% with messages = get_flashed_messages() %} + {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} -
      - - {% for message in messages %} -
    • {{ message }}
    • +
        + {% for category, message in messages %} +
      • {{ message }}
      • {% endfor %}
      {% endif %} @@ -60,7 +63,9 @@
      + {% if not g.user.logo %}
      + {% endif %}
      {% if g.doob%} @@ -78,9 +83,10 @@ {% endif %}
        {% include 'sidenav.html' %} -
      -
      +
    +
    +
    {% block content %} @@ -91,6 +97,7 @@
    + {% cache 60*5 %}
    Flask & Steam @@ -101,10 +108,23 @@ YouTube
    + {% endcache %}
    {% block pagescripts %} {% endblock %} + - diff --git a/templates/profile.html b/templates/profile.html index 4e24d7b..f20a185 100644 --- a/templates/profile.html +++ b/templates/profile.html @@ -7,22 +7,31 @@

     {{ user.nickname }}

    -
    - Steam | - Forum Profile | - Dotabuff +
    + {% if user.public %} {% if user.bio_text == None %} This user's profile bio is empty! {% else %} {{ user.bio_text }} {% endif %} + {% else %} + This user profile is set to private + {% endif %} {% if user.id == g.user.id %} {% endif %} -
    +
    + {% if user.public %}
    Current Hero
    {{ user.random_hero['localized_name'] }}
    @@ -31,11 +40,13 @@ View A-Z Progress
    -
      -
    • Points: 0
    • -
    • Last Seen:
    • -
    • Heroes Randomed: {{ user.random_heroes.completed | length }}
    • +
        +
      • Completed {{ user.random_heroes.completed | length }} heroes in A-Z
      • +
      • Has 0 doobs points
      • +
      • Last seen at {{ user.last_seen | js_datetime }}
      • +
      • Doob since {{ user.created | js_datetime }}
      + {% endif %}
    {% endblock %} diff --git a/templates/settings.html b/templates/settings.html index fd0330d..ee5a578 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -5,21 +5,20 @@ {% block content %}
    -

     {{ user.nickname }}

    +

     {{ g.user.nickname }}'s Settings

    -
    +
    {{ form.hidden_tag() }}
    - Settings
    • -
    • -
    • +
    diff --git a/templates/sidenav.html b/templates/sidenav.html index 3ab9191..147443f 100644 --- a/templates/sidenav.html +++ b/templates/sidenav.html @@ -17,15 +17,16 @@
  • Social
  • -
  • Board
  • -
  • YouTube
  • -
  • IRC Chat
  • +
  • Board
  • +
  • YouTube
  • +
  • IRC Chat
  • +
  • Controls
  • {% if not g.user%} -
  • Login
  • -
  • Register
  • +
  • Login
  • +
  • Register
  • {% else %} -
  • Profile
  • -
  • Settings
  • -
  • Logout
  • +
  • Profile
  • +
  • Settings
  • +
  • Logout
  • {% endif %} diff --git a/templates/teamspeak.html b/templates/teamspeak.html index e4e0e84..cb14954 100644 --- a/templates/teamspeak.html +++ b/templates/teamspeak.html @@ -13,9 +13,9 @@

    Recent Activity

      -
    • Active users connected:
    • -
    • Total users connected: {{ ts3_current_clients() }}
    • -
    • Countries active on server:
    • +
    • Users currently connected:
    • +
    • Unique users this week:
    • +
    • Countries active this week:
    @@ -38,13 +38,14 @@ {% block pagescripts %} {% cache 60*5 %} {% set teamspeak_data = get_teamspeak_window() %} - - - + + +