diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dd1156f --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +.env +.flaskenv +dist/ +build/ +.cache/ +.pytest_cache/ +.vscode \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..9a07e1f --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Typefight +Typefight is a typing game where you get a random sentence, type it in, and see your score, as well as other people's score. + +This app comes from my desire to learn about databases and how to interact with them. In this case, I'm using python's Flask framework for the backend. + +## Features +The game randomly assigns the player a short sentence, which they must type (including characters like spaces, periods, commas, etc.). After which, the player gets the time it took them to type in that sentence, and how long it takes other players who've typed the same sentence. + +## Tech stack +- HTML, CSS & Javascript +- Docker containers +- Postgresql 13 +- Python 3.8 + - Flask + - psycopg2 \ No newline at end of file diff --git a/database/Dockerfile b/database/Dockerfile new file mode 100644 index 0000000..e271d6d --- /dev/null +++ b/database/Dockerfile @@ -0,0 +1,9 @@ +FROM postgres:13-alpine + +# Setting timezone to Los Angeles +RUN apk add -U tzdata +RUN ["cp", "/usr/share/zoneinfo/America/Los_Angeles", "/etc/localtime"] + +# Initializing database extensions and tables +COPY create-extension.sh /docker-entrypoint-initdb.d/ +COPY initdb.sql /docker-entrypoint-initdb.d/ \ No newline at end of file diff --git a/database/create-extension.sh b/database/create-extension.sh new file mode 100644 index 0000000..3cca526 --- /dev/null +++ b/database/create-extension.sh @@ -0,0 +1,4 @@ +psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" "$POSTGRES_DB" << EOF +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; +SELECT * FROM pg_extension; +EOF \ No newline at end of file diff --git a/database/initdb.sql b/database/initdb.sql new file mode 100644 index 0000000..2e0b1eb --- /dev/null +++ b/database/initdb.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS highscores( + highscore_uid UUID PRIMARY KEY, + score NUMERIC(6, 2) NOT NULL CHECK (score > 0) +); + +CREATE TABLE IF NOT EXISTS players( + player_uid UUID PRIMARY KEY, + player_name CHAR(3) UNIQUE NOT NULL, + highscore_uid UUID REFERENCES highscores(highscore_uid) ON DELETE CASCADE NOT NULL, + CONSTRAINT FK_Highscores UNIQUE (highscore_uid) +); diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..6490984 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,36 @@ +version: "3.8" +services: + web: + build: + context: ${PWD}/src + image: typefight-flask:1.0 + container_name: typefight-flask + ports: + - 5000:5000 + environment: + - FLASK_APP=${FLASK_MODULE} + - FLASK_ENV=${FLASK_ENV} + # Remove this in production + - FLASK_RUN_HOST=0.0.0.0 + volumes: + - ${PWD}/src/typefight:/var/app/typefight + depends_on: + - database + database: + build: + context: ${PWD}/database + image: typefight-db:1.0 + container_name: typefight-postgresql + ports: + - 5432:5432 + environment: + - POSTGRES_USER=${DB_USER} + - POSTGRES_PASSWORD=${DB_PASSWORD} + - POSTGRES_DB=${DB_NAME} + - PGTZ=America/Los_Angeles + volumes: + - typefight-db:/var/lib/postgresql/data +volumes: + typefight-db: + driver: local + name: typefight-db \ No newline at end of file diff --git a/src/Dockerfile b/src/Dockerfile new file mode 100644 index 0000000..b450488 --- /dev/null +++ b/src/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3.9.5-slim-buster + +WORKDIR /var/app/ + +COPY requirements.txt . +COPY typefight/ ./typefight/ + +RUN pip install --no-cache-dir -r requirements.txt + +CMD ["flask", "run"] \ No newline at end of file diff --git a/src/requirements.txt b/src/requirements.txt new file mode 100644 index 0000000..6bb27d3 --- /dev/null +++ b/src/requirements.txt @@ -0,0 +1,2 @@ +flask +psycopg2-binary \ No newline at end of file diff --git a/src/typefight/__init__.py b/src/typefight/__init__.py new file mode 100644 index 0000000..50d33ff --- /dev/null +++ b/src/typefight/__init__.py @@ -0,0 +1,16 @@ +import os +from flask import Flask + +def create_app(): + app = Flask(__name__, instance_relative_config=True) + + try: + os.makedirs(app.instance_path) + except OSError: + pass + + @app.route("/hello") + def hello(): + return "Hello, world!" + + return app \ No newline at end of file