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

Set secret UI #85

Merged
merged 2 commits into from
Mar 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ repos:
hooks:
- id: ruff
name: ruff
entry: ruff --fix
entry: ruff check --fix
language: system
types: [python]
- id: ruff-format
Expand Down
1 change: 1 addition & 0 deletions alembic/versions/23e3fa471b40_add_user_clue_count_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Create Date: 2024-01-09 17:44:57.981253

"""

from typing import Sequence
from typing import Union

Expand Down
1 change: 1 addition & 0 deletions alembic/versions/6777d9f1937f_fine_tune_indexes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Create Date: 2024-03-05 17:11:50.533412

"""

from typing import Sequence
from typing import Union

Expand Down
1 change: 1 addition & 0 deletions alembic/versions/734535a7c997_secret_word_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Create Date: 2024-01-14 18:09:54.747781

"""

from typing import Sequence
from typing import Union

Expand Down
1 change: 1 addition & 0 deletions alembic/versions/8240e5d61928_user_subscription_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Create Date: 2024-01-15 16:15:44.306258

"""

from typing import Sequence
from typing import Union

Expand Down
1 change: 1 addition & 0 deletions alembic/versions/8798f64b5f19_hot_clue_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Create Date: 2024-01-17 21:31:45.610168

"""

from typing import Sequence
from typing import Union

Expand Down
3 changes: 2 additions & 1 deletion alembic/versions/c4ee2484db71_user_user_history_tables.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
"""user + user history tables

Revision ID: c4ee2484db71
Revises:
Revises:
Create Date: 2024-01-09 17:19:56.323607

"""

from typing import Sequence
from typing import Union

Expand Down
1 change: 1 addition & 0 deletions alembic/versions/edef17c40466_add_indices.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Create Date: 2024-03-03 14:19:35.170844

"""

from typing import Sequence
from typing import Union

Expand Down
3 changes: 2 additions & 1 deletion logic/game_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ async def set_secret(self, secret: str, clues: list[str]) -> None:
session.add(db_secret)
with hs_transaction(self.session) as session:
for clue in clues:
session.add(tables.HotClue(secret_word_id=db_secret.id, clue=clue))
if clue:
session.add(tables.HotClue(secret_word_id=db_secret.id, clue=clue))

async def get_all_secrets(
self, with_future: bool
Expand Down
1,523 changes: 803 additions & 720 deletions poetry.lock

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ readme = "README.md"
[tool.poetry.dependencies]
python = "^3.11"
redis = "^5.0.1"
fastapi = "^0.105.0"
fastapi = "0.110.0"
jinja2 = "^3.1.2"
motor = "^3.3.2"
numpy = "^1.26.2"
Expand All @@ -33,11 +33,13 @@ mypy = "^1.8.0"
types-python-dateutil = "^2.8.19.14"
types-requests = "^2.31.0.10"
types-redis = "^4.6.0.11"
ruff = "^0.1.9"
ruff = "0.3.4"
alembic = "^1.13.1"

[tool.ruff]
fix = true

[tool.ruff.lint]
select = ["F", "I"]


Expand Down
2 changes: 2 additions & 0 deletions routers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env python
from routers.admin_routes import admin_router
from routers.auth_routes import auth_router
from routers.game_routes import game_router
from routers.legal_routes import legal_router
Expand All @@ -7,6 +8,7 @@
from routers.user_routes import user_router

routers = [
admin_router,
auth_router,
game_router,
pages_router,
Expand Down
80 changes: 80 additions & 0 deletions routers/admin_routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import datetime
import random

from fastapi import APIRouter
from fastapi import Depends
from fastapi.requests import Request
from fastapi.responses import HTMLResponse
from pydantic import BaseModel
from sqlmodel import Session

from common.session import hs_transaction
from logic.game_logic import SecretLogic, CacheSecretLogic
from model import GensimModel
from routers.base import render
from routers.base import super_admin
from sqlmodel import select
from common import tables

TOP_SAMPLE = 10000

admin_router = APIRouter(prefix="/admin", dependencies=[Depends(super_admin)])


@admin_router.get("/set-secret", response_class=HTMLResponse, include_in_schema=False)
async def index(request: Request) -> HTMLResponse:
model = request.app.state.model
secret_logic = SecretLogic(request.app.state.session)
all_secrets = await secret_logic.get_all_secrets(with_future=True)
potential_secrets = []
while len(potential_secrets) < 45:
secret = await get_random_word(model) # todo: in batches
if secret not in all_secrets:
potential_secrets.append(secret)

return render(name="set_secret.html", request=request, potential_secrets=potential_secrets)


@admin_router.get("/model", include_in_schema=False)
async def get_word_data(request: Request, word: str) -> dict[str, list[str] | datetime.date]:
session = request.app.state.session
redis = request.app.state.redis
model = request.app.state.model
logic = CacheSecretLogic(session=session, redis=redis, secret=word, dt=await get_date(session), model=model)
await logic.simulate_set_secret(force=False)
cache = await logic.cache
return {
"date": logic.date_,
"data": cache[::-1],
}

class SetSecretRequest(BaseModel):
secret: str
clues: list[str]

@admin_router.post("/set-secret", include_in_schema=False)
async def set_new_secret(request: Request, set_secret: SetSecretRequest):
session = request.app.state.session
redis = request.app.state.redis
model = request.app.state.model
logic = CacheSecretLogic(session=session, redis=redis, secret=set_secret.secret, dt=await get_date(session), model=model)
await logic.simulate_set_secret(force=False)
await logic.do_populate(set_secret.clues)
return f"Set '{set_secret.secret}' with clues '{set_secret.clues}' on {logic.date_}"



# TODO: everything below here should be in a separate file, and set_secret script should be updated to use it
async def get_random_word(model: GensimModel) -> str:
rand_index = random.randint(0, TOP_SAMPLE)
return model.model.index_to_key[rand_index]


async def get_date(session: Session) -> datetime.date:
query = select(tables.SecretWord.game_date) # type: ignore
query = query.order_by(tables.SecretWord.game_date.desc()) # type: ignore
with hs_transaction(session) as s:
latest: datetime.date = s.exec(query).first()

dt = latest + datetime.timedelta(days=1)
return dt
19 changes: 13 additions & 6 deletions routers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@
from typing import TYPE_CHECKING

from fastapi import FastAPI
from fastapi import HTTPException
from fastapi import status
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse

from fastapi import Request
from logic.game_logic import CacheSecretLogic
from logic.game_logic import VectorLogic
from logic.user_logic import UserLogic

templates = Jinja2Templates(directory="templates")

if TYPE_CHECKING:
from typing import Any

from fastapi import Request
from fastapi.responses import Response


def get_date(delta: datetime.timedelta) -> datetime.date:
return datetime.datetime.utcnow().date() - delta
Expand All @@ -43,10 +45,15 @@ async def get_logics(
return logic, cache_logic


def render(name: str, request: Request, **kwargs: Any) -> Response:
def super_admin(request: Request) -> None:
user = request.state.user
if not user or not UserLogic.has_permissions(user, UserLogic.SUPER_ADMIN):
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)


def render(name: str, request: Request, **kwargs: Any) -> HTMLResponse:
kwargs["js_version"] = request.app.state.js_version
kwargs["css_version"] = request.app.state.css_version
kwargs["request"] = request
kwargs["enumerate"] = enumerate
kwargs["google_auth_client_id"] = request.app.state.google_app["client_id"]
return templates.TemplateResponse(name, context=kwargs)
return templates.TemplateResponse(request=request, name=name, context=kwargs)
11 changes: 3 additions & 8 deletions routers/pages_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
from logic.game_logic import VectorLogic
from logic.user_logic import UserClueLogic
from logic.user_logic import UserHistoryLogic
from logic.user_logic import UserLogic
from logic.user_logic import UserStatisticsLogic
from routers.base import get_date
from routers.base import get_logics
from routers.base import render
from routers.base import super_admin

pages_router = APIRouter()

Expand Down Expand Up @@ -50,7 +50,7 @@ async def index(request: Request) -> Response:
get_date(request.app.state.days_delta),
)
history = json.dumps(
[historia.dict() for historia in await history_logic.get_history()]
[historia.model_dump() for historia in await history_logic.get_history()]
)
else:
history = ""
Expand Down Expand Up @@ -103,9 +103,7 @@ async def yesterday_top(request: Request) -> Response:
@pages_router.get("/secrets", response_class=HTMLResponse)
async def secrets(request: Request, with_future: bool = False) -> Response:
if with_future:
user = request.state.user
if not user or not UserLogic.has_permissions(user, UserLogic.SUPER_ADMIN):
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
super_admin(request)

logic, _ = await get_logics(app=request.app)
all_secrets = await logic.secret_logic.get_all_secrets(with_future=with_future)
Expand All @@ -119,12 +117,9 @@ async def secrets(request: Request, with_future: bool = False) -> Response:

@pages_router.get("/faq", response_class=HTMLResponse, include_in_schema=False)
async def faq(request: Request) -> Response:
# _, cache_logic = await get_logics(app=request.app, delta=timedelta(days=1))
# cache = await cache_logic.cache
return render(
name="faq.html",
request=request,
# yesterday=cache[-11:]
yesterday=[],
)

Expand Down
1 change: 1 addition & 0 deletions scripts/set_secret.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ async def main() -> None:
)
parser.add_argument(
"--top-sample",
default=10000,
type=int,
help="Top n words to choose from when choosing a random word. If not provided, will use all words in the model.",
)
Expand Down
Loading
Loading