Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
silasary committed Dec 4, 2019
1 parent 921beee commit f4b5c0f
Show file tree
Hide file tree
Showing 11 changed files with 212 additions and 243 deletions.
9 changes: 2 additions & 7 deletions logsite/__init__.py
Expand Up @@ -10,8 +10,7 @@

APP = PDFlask(__name__)

APP.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
APP.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://{user}:{password}@{host}:{port}/{db}'.format(
APP.config['DATABASE_URI'] = 'mysql://{user}:{password}@{host}:{port}/{db}'.format(
user=configuration.get('mysql_user'),
password=configuration.get('mysql_passwd'),
host=configuration.get('mysql_host'),
Expand All @@ -21,11 +20,7 @@
from . import db, stats, api, views # isort:skip # pylint: disable=wrong-import-position, unused-import

def __create_schema() -> None:
engine = create_engine(APP.config['SQLALCHEMY_DATABASE_URI'])
if not database_exists(engine.url):
create_database(engine.url)
db.DB.create_all()
engine.dispose()
pass

APP.config['commit-id'] = subprocess.check_output(['git', 'rev-parse', 'HEAD'])
APP.config['branch'] = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip().decode()
Expand Down
33 changes: 15 additions & 18 deletions logsite/data/game.py
@@ -1,46 +1,43 @@
from typing import Dict

import sqlalchemy as sa
import peewee

from .. import db
from ..db import DB as fsa

CLEARANCE_PUBLIC = 0 # Anyone can view
CLEARANCE_PLAYERS = 1 # Players in the game can view
CLEARANCE_MODS = 2 # Mods, TOs, etc
CLEARANCE_ADMIN = 3 # Debug info, developer eyes only.

class Game(fsa.Model): # type: ignore
__tablename__ = 'game'
id = sa.Column(fsa.Integer, primary_key=True, autoincrement=False)
match_id = sa.Column(sa.Integer, sa.ForeignKey('match.id'), nullable=False)
winner_id = sa.Column(sa.Integer, sa.ForeignKey('user.id'), nullable=True)
log = fsa.Column(sa.Text)
winner = fsa.relationship('User')
class Game(db.BaseModel): # type: ignore
id = peewee.IntegerField(primary_key=True)
match_id = peewee.DeferredForeignKey('Match', backref='games')
winner_id = peewee.DeferredForeignKey('User')

log = peewee.TextField()


def sanitized_log(self) -> str:
if 'Exception:' in self.log:
return 'Log is not visible at this time. Please contact Silasary.'
# If we want to remove chat, or OOB messages, do that here.
return self.log.strip()
return str(self.log).strip()

def to_dict(self) -> Dict:
return {
'id': self.id,
'match_id': self.match_id,
'winner': self.winner,
'winner': self.winner_id,
'log': self.log,
}

def insert_game(game_id: int, match_id: int, game_lines: str) -> None:
local = Game(id=game_id, match_id=match_id, log=game_lines)
db.merge(local) # This will replace an old version of the game, if one exists.
db.commit()
Game.insert({'id':game_id, 'match_id':match_id, 'log':game_lines}).on_conflict_replace().execute()

def get_game(game_id: int) -> Game:
return Game.query.filter_by(id=game_id).one_or_none()

class Line(fsa.Model): #type: ignore
id = sa.Column(fsa.Integer, primary_key=True, autoincrement=True)
game_id = sa.Column(sa.Integer, sa.ForeignKey('game.id'), nullable=False)
clearance = sa.Column(sa.Integer, nullable=True)
class Line(db.BaseModel): #type: ignore
id = peewee.AutoField()
game_id = peewee.DeferredForeignKey('Game')
clearance = peewee.IntegerField(null=True)
64 changes: 33 additions & 31 deletions logsite/data/match.py
Expand Up @@ -2,40 +2,35 @@
from typing import Any, Dict, List

import pytz
import sqlalchemy as sa # type: ignore
import peewee
from flask import url_for

from shared import dtutil

from .. import db
from ..db import DB as fsa # type: ignore

# pylint: disable=no-member

class Match(fsa.Model): # type: ignore
__tablename__ = 'match'
id = sa.Column(sa.Integer, primary_key=True, autoincrement=False)
format_id = sa.Column(sa.Integer, sa.ForeignKey('format.id'))
comment = sa.Column(sa.String(200))
start_time = sa.Column(sa.DateTime)
end_time = sa.Column(sa.DateTime)

has_unexpected_third_game = sa.Column(sa.Boolean)
is_league = sa.Column(sa.Boolean)
is_tournament = sa.Column(sa.Boolean)
# is_timeout = sa.Column(sa.Boolean)

players = fsa.relationship('User', secondary=db.MATCH_PLAYERS)
modules = fsa.relationship('Module', secondary=db.MATCH_MODULES)
games = fsa.relationship('Game', backref='match')
format = fsa.relationship('Format')
tournament = fsa.relationship('TournamentInfo', backref='match')
class Match(db.BaseModel): # type: ignore
id = peewee.IntegerField(primary_key=True)
format_id = peewee.ForeignKeyField(db.Format)
comment = peewee.CharField(max_length=200)
start_time = peewee.DateTimeField(null=True)
end_time = peewee.DateTimeField(null=True)

has_unexpected_third_game = peewee.BooleanField(null=True)
is_league = peewee.BooleanField(null=True)
is_tournament = peewee.BooleanField(null=True)
# is_timeout = peewee.BooleanField()

# players = fsa.relationship('User', secondary=db.MATCH_PLAYERS)
# modules = fsa.relationship('Module', secondary=db.MATCH_MODULES)
# tournament = fsa.relationship('TournamentInfo', backref='match')

def url(self) -> str:
return url_for('show_match', match_id=self.id)

def format_name(self) -> str:
return self.format.get_name()
return self.format_id.get_name()

def host(self) -> db.User:
return self.players[0]
Expand All @@ -49,7 +44,7 @@ def other_player_names(self) -> List[str]:
def set_times(self, start_time: int, end_time: int) -> None:
self.start_time = dtutil.ts2dt(start_time)
self.end_time = dtutil.ts2dt(end_time)
db.commit()
self.save()

def start_time_aware(self) -> datetime.datetime:
return pytz.utc.localize(self.start_time)
Expand All @@ -62,6 +57,10 @@ def display_date(self) -> str:
return ''
return dtutil.display_date(self.start_time_aware())

@property
def players(self):
return db.User.select().join(db.MatchPlayers).join(Match).where(Match.id == self.id)

def to_dict(self) -> Dict:
return {
'id': self.id,
Expand All @@ -74,24 +73,27 @@ def to_dict(self) -> Dict:
'tournament': self.tournament if self.tournament is not None else None,
}

def create_match(match_id: int, format_name: str, comment: str, modules: List[str], players: List[str]) -> Match:
def get_or_insert_match(match_id: int, format_name: str, comment: str) -> Match:
format_id = db.get_or_insert_format(format_name).id
local = Match(id=match_id, format_id=format_id, comment=comment)
return Match.get_or_create(id=match_id, defaults={'format_id':format_id, 'comment':comment})[0]


def create_match(match_id: int, format_name: str, comment: str, modules: List[str], players: List[str]) -> Match:
local = get_or_insert_match(match_id, format_name, comment)
modules = [db.get_or_insert_module(mod) for mod in modules]
local.modules = modules
local.players = [db.get_or_insert_user(user) for user in set(players)]
db.add(local)
db.commit()
local.save()
return local

def get_match(match_id: int) -> Match:
return Match.query.filter_by(id=match_id).one_or_none()
return Match.get_or_none(id=match_id)

def get_recent_matches() -> Any:
return Match.query.order_by(Match.id.desc())
return Match.select().order_by(Match.id.desc())

def get_recent_matches_by_player(name: str) -> Any:
return Match.query.filter(Match.players.any(db.User.name == name)).order_by(Match.id.desc())
return Match.select().join(db.MatchPlayers).join(db.User).where(db.User.name == name).order_by(Match.id.desc())

def get_recent_matches_by_format(format_id: int) -> Any:
return Match.query.filter(Match.format_id == format_id).order_by(Match.id.desc())
return Match.select().where(Match.format_id == format_id).order_by(Match.id.desc())
37 changes: 14 additions & 23 deletions logsite/data/tournament.py
@@ -1,18 +1,15 @@
from typing import Dict

import sqlalchemy as sa # type: ignore
import peewee

from .. import db
from ..db import DB as fsa # type: ignore


class TournamentInfo(fsa.Model): # type: ignore
__tablename__ = 'match_tournament'
id = sa.Column(sa.Integer, primary_key=True)
match_id = sa.Column(sa.Integer, sa.ForeignKey('match.id'), nullable=False)
tournament_id = sa.Column(sa.Integer, sa.ForeignKey(
'tournament.id'), nullable=False)
round_num = sa.Column(sa.Integer)
class TournamentInfo(db.BaseModel): # type: ignore
id = peewee.AutoField()
match_id = peewee.DeferredForeignKey('Match')
tournament_id = peewee.DeferredForeignKey('Tournament')
round_num = peewee.IntegerField()

def to_dict(self) -> Dict:
return {
Expand All @@ -22,27 +19,21 @@ def to_dict(self) -> Dict:
'rount_num': self.round_num,
}


class Tournament(fsa.Model): # type: ignore
__tablename__ = 'tournament'
id = sa.Column(sa.Integer, primary_key=True)
name = sa.Column(sa.String(length=200), unique=True, index=True)
active = sa.Column(sa.Boolean)
class Tournament(db.BaseModel): # type: ignore
id = peewee.AutoField()
name = peewee.CharField(max_length=200, unique=True, index=True)
active = peewee.BooleanField()


def get_tournament(name: str) -> Tournament:
return Tournament.query.filter_by(name=name).one_or_none()


def create_tournament(name: str) -> Tournament:
local = Tournament(name=name, active=True)
db.add(local)
db.commit()
return local
local = Tournament.get_or_create(name=name, defaults={'active': True})
return local[0]


def create_tournament_info(match_id: int, tournament_id: int) -> TournamentInfo:
local = TournamentInfo(match_id=match_id, tournament_id=tournament_id)
db.add(local)
db.commit()
return local
local = TournamentInfo.get_or_create(match_id=match_id, tournament_id=tournament_id)
return local[0]
102 changes: 39 additions & 63 deletions logsite/db.py
@@ -1,95 +1,71 @@
from typing import Any, Optional
from typing import Optional

import sqlalchemy as sa
import peewee
from flask import url_for
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm.exc import MultipleResultsFound
from playhouse import db_url
import peeweedbevolve

from . import APP

# pylint: disable=no-member

DB = SQLAlchemy(APP) # type: ignore
MIGRATE = Migrate(APP, DB)
DB = db_url.connect(APP.config['DATABASE_URI'])

MATCH_PLAYERS = DB.Table('match_players',
DB.Column('match_id', DB.Integer, DB.ForeignKey('match.id'), primary_key=True),
DB.Column('user_id', DB.Integer, DB.ForeignKey('user.id'), primary_key=True)
)
class BaseModel(peewee.Model):
class Meta:
database = DB

MATCH_MODULES = DB.Table('match_modules',
DB.Column('match_id', DB.Integer, DB.ForeignKey('match.id'), primary_key=True),
DB.Column('module_id', DB.Integer, DB.ForeignKey('module.id'), primary_key=True)
)
class MatchPlayers(BaseModel):
match_id = peewee.DeferredForeignKey('Match')
user_id = peewee.DeferredForeignKey('User')

class User(DB.Model): # type: ignore
__tablename__ = 'user'
id = sa.Column(sa.Integer, primary_key=True)
name = sa.Column(sa.String(60))
discord_id = sa.Column(sa.String(200))

class MatchModules(BaseModel):
match_id = peewee.DeferredForeignKey('Match')
user_id = peewee.DeferredForeignKey('Module')

class User(BaseModel): # type: ignore
id = peewee.AutoField()
name = peewee.CharField(max_length=60, unique=True)
discord_id = peewee.CharField(max_length=200)

def url(self) -> str:
return url_for('show_person', person=self.name)

class Format(DB.Model): # type: ignore
__tablename__ = 'format'
id = sa.Column(sa.Integer, primary_key=True)
name = sa.Column(sa.String(40))
friendly_name = sa.Column(sa.String(40))
class Format(BaseModel): # type: ignore
id = peewee.AutoField()
name = peewee.CharField(max_length=40, unique=True)
friendly_name = peewee.CharField(max_length=40)

def get_name(self) -> str:
if self.friendly_name:
return self.friendly_name
return self.name

class Module(DB.Model): # type: ignore
__tablename__ = 'module'
id = sa.Column(sa.Integer, primary_key=True)
name = sa.Column(sa.String(50))
class Module(BaseModel): # type: ignore
id = peewee.AutoField()
name = peewee.CharField(max_length=50)

def commit() -> None:
return DB.session.commit()
# def commit() -> None:
# return DB.session.commit()

def add(item: Any) -> None:
return DB.session.add(item)
# def add(item: Any) -> None:
# return DB.session.add(item)

def merge(item: Any) -> None:
return DB.session.merge(item)
# def merge(item: Any) -> None:
# return DB.session.merge(item)

def delete(item: Any) -> None:
return DB.session.delete(item)
# def delete(item: Any) -> None:
# return DB.session.delete(item)

def get_format(name: str) -> Optional[Format]:
return Format.query.filter_by(name=name).one_or_none()
return Format.get_or_none(Format.name == name)

def get_or_insert_format(name: str) -> Format:
local = get_format(name)
if local is not None:
return local
local = Format(name=name)
add(local)
commit()
return local
return Format.get_or_create(name=name)[0]

def get_or_insert_module(name: str) -> Module:
local = Module.query.filter_by(name=name).one_or_none()
if local is not None:
return local
local = Module(name=name)
add(local)
commit()
return local
return Module.get_or_create(name=name)[0]

def get_or_insert_user(name: str) -> User:
try:
local = User.query.filter_by(name=name).one_or_none()
if local is not None:
return local
local = User(name=name)
add(local)
commit()
return local
except MultipleResultsFound:
query = User.query.filter_by(name=name)
return query.first()
return User.get_or_create(name=name)[0]

0 comments on commit f4b5c0f

Please sign in to comment.