Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add SQLAlchemy, more structure, and Rotation model #2

Merged
merged 3 commits into from Mar 26, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Expand Up @@ -2,3 +2,9 @@ scrape/keys.*
connect/core/connect.php
css/sass/.sass-cache/
*.swp

# VSCode
.vscode/

# macOS
.DS_Store
9 changes: 7 additions & 2 deletions backend/Dockerfile
Expand Up @@ -4,8 +4,10 @@ FROM python:3.9-slim-buster
# set work directory
WORKDIR /usr/src/app

# set environment varibles
# set environment variables
# prevents python from writing pyc files to disk
ENV PYTHONDONTWRITEBYTECODE 1
# prevents python from buffering stdout and stderr
ENV PYTHONUNBUFFERED 1

# install dependencies
Expand All @@ -18,5 +20,8 @@ COPY . /usr/src/app/
# flask app environment variable
ENV FLASK_APP app.py

# open port 5000 for requests
EXPOSE 5000

# start server
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
CMD ["flask", "run", "--host=0.0.0.0"]
67 changes: 0 additions & 67 deletions backend/app.py

This file was deleted.

30 changes: 30 additions & 0 deletions backend/app/__init__.py
@@ -0,0 +1,30 @@
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

# Define the WSGI application object
app = Flask(__name__, instance_relative_config=True)

# Configurations
app.config.from_object('config')

# Set the database connection string
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'

# Define the database object which is imported
# by modules and controllers
db = SQLAlchemy(app)

# Import models for DB schema creation
from .models.rotation import Rotation
from .models.champion import Champion

# Build the database:
# This will create the database file using SQLAlchemy, necessary for views
db.create_all()

from .views.champions import champions_api
from .views.rotations import rotations_api

# Register blueprint(s)
app.register_blueprint(champions_api)
app.register_blueprint(rotations_api)
Empty file added backend/app/models/__init__.py
Empty file.
34 changes: 34 additions & 0 deletions backend/app/models/champion.py
@@ -0,0 +1,34 @@
from sqlalchemy import Column, Date, Integer, String
from sqlalchemy.orm import relationship

from app import db
from .champion_rotation import champion_rotation

CHAMPION_SQUARE_IMAGE_URL_PREFIX = 'https://ddragon.leagueoflegends.com/cdn/5.15.1/img/champion/'
CHAMPION_TALL_IMAGE_URL_PREFIX = 'https://ddragon.leagueoflegends.com/cdn/img/champion/loading/'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please update the links, thank you



class Champion(db.Model):
__tablename__ = 'champions'
id = Column(Integer, primary_key=True)
name = Column(String(50), unique=True)
key = Column(String(50), unique=True)
title = Column(String(50))
tags = Column(String(255))
date_released = Column(Date)
rotations = relationship('Rotation', secondary=champion_rotation, back_populates='champions')

def to_dict(self) -> dict:
return {
'id': self.id,
'name': self.name,
'key': self.key,
'title': self.title,
'tags': self.tags,
'dateRelease': self.date_released.isoformat(),
'squareImage': '{prefix}{key}.png'.format(prefix=CHAMPION_SQUARE_IMAGE_URL_PREFIX, key=self.key),
'tallImage': '{prefix}{key}_0.jpg'.format(prefix=CHAMPION_TALL_IMAGE_URL_PREFIX, key=self.key)
}

def __repr__(self) -> str:
return '<Champion %r>' % (self.name)
9 changes: 9 additions & 0 deletions backend/app/models/champion_rotation.py
@@ -0,0 +1,9 @@
from sqlalchemy import Column, ForeignKey, Integer, Table

from app import db


champion_rotation = Table('champion_rotations', db.Model.metadata,
Column('rotation_id', Integer, ForeignKey('rotations.week_number')),
Column('champion_id', Integer, ForeignKey('champions.id'))
)
23 changes: 23 additions & 0 deletions backend/app/models/rotation.py
@@ -0,0 +1,23 @@
from sqlalchemy import Column, Date, Integer
from sqlalchemy.orm import relationship

from app import db
from .champion_rotation import champion_rotation


class Rotation(db.Model):
__tablename__ = 'rotations'
week_number = Column(Integer, primary_key=True)
start_date = Column(Date)
end_date = Column(Date)
champions = relationship('Champion', secondary=champion_rotation, back_populates='rotations')

def to_dict(self) -> dict:
return {
'weekNumber': self.week_number,
'startDate': self.start_date.isoformat(),
'endDate': self.end_date.isoformat()
}

def __repr__(self) -> str:
return '<Rotation %d>' % (self.week_number)
Empty file added backend/app/views/__init__.py
Empty file.
36 changes: 36 additions & 0 deletions backend/app/views/champions.py
@@ -0,0 +1,36 @@
from flask import Blueprint, jsonify

from ..models.champion import Champion

champions_api = Blueprint('champions', __name__, url_prefix='/api/champions')


@champions_api.route('/', methods=['GET'])
def get_champions():
"""
API call that returns all champions.

Returns:
JSON representation of all champions
"""
champions = [champion.to_dict() for champion in Champion.query.all()]
return jsonify(champions)


@champions_api.route('/<int:id>/', methods=['GET'])
def get_champion(id):
"""
API call that returns a single champion by its supplied ID

Parameters:
id (int): champion ID

Returns:
JSON representation of champion with corresponding ID
"""
champion = Champion.query.filter_by(id=id).first()
if not champion:
# If empty query, return 404 error
return 'Could not find champion with supplied ID', 404

return champion.to_dict()
15 changes: 15 additions & 0 deletions backend/app/views/rotations.py
@@ -0,0 +1,15 @@
from flask import Blueprint, jsonify

from ..models.rotation import Rotation

rotations_api = Blueprint('rotations', __name__, url_prefix='/api/rotations')


@rotations_api.route('/<int:week>', methods=['GET'])
def get_rotation_week(week: int):
"""
Returns a JSON representation of all free champions for the given rotation week.
"""
rotations = Rotation.query.filter(Rotation.week_number == week)
champions = [rotation.champions.to_dict() for rotation in rotations]
return jsonify(champions)
6 changes: 6 additions & 0 deletions backend/config.py
@@ -0,0 +1,6 @@
import os

DEBUG = False
SECRET_KEY = os.urandom(24)
SQLALCHEMY_ECHO = False
SQLALCHEMY_TRACK_MODIFICATIONS = False
7 changes: 0 additions & 7 deletions backend/entrypoint.sh

This file was deleted.

3 changes: 0 additions & 3 deletions backend/init.py

This file was deleted.

1 change: 1 addition & 0 deletions backend/requirements.txt
@@ -1 +1,2 @@
Flask-SQLAlchemy
flask
6 changes: 6 additions & 0 deletions backend/run.py
@@ -0,0 +1,6 @@
# This file is for running the app in development, and should
# be substituted by Gunicorn in production.
from app import app

app.run(host='0.0.0.0', port=5000, debug=True, threaded=True)
print('champion-rotation-predictor started.')
6 changes: 0 additions & 6 deletions backend/schema.sql

This file was deleted.

4 changes: 0 additions & 4 deletions champion/.htaccess

This file was deleted.

63 changes: 0 additions & 63 deletions core/classes/read.php

This file was deleted.

13 changes: 0 additions & 13 deletions core/connect/connect.php

This file was deleted.