Merge pull request 'postgres-migration' (#1) from postgres-migration into main
All checks were successful
Build Docker Image / build (push) Successful in 3m21s

Reviewed-on: #1
This commit is contained in:
cal 2026-02-05 19:43:13 +00:00
commit 65c00800d2
13 changed files with 377 additions and 8622 deletions

375
.gitea/workflows/build.yml Normal file
View File

@ -0,0 +1,375 @@
# Gitea Actions: Docker Build, Push, and Notify
#
# This workflow provides a complete CI/CD pipeline for Paper Dynasty Database:
# - Validates semantic versioning on PRs
# - Builds Docker images on every push/PR
# - Pushes to Docker Hub on main branch merges
# - Sends Discord notifications on success/failure
#
# Created: 2026-02-05
# For: Paper Dynasty Database API
name: Build Docker Image
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
# ==============================================
# 1. CHECKOUT CODE
# ==============================================
- name: Checkout code
uses: actions/checkout@v4
# ==============================================
# 2. SEMANTIC VERSION VALIDATION (PRs only)
# ==============================================
# Enforces proper semantic versioning:
# - Blocks PRs that don't bump VERSION file
# - Validates version changes follow semver rules
# - Prevents skipping versions or going backwards
#
# Valid bumps:
# - Patch: 1.2.3 → 1.2.4 (bug fixes)
# - Minor: 1.2.3 → 1.3.0 (new features)
# - Major: 1.2.3 → 2.0.0 (breaking changes)
#
# Invalid bumps:
# - 1.2.3 → 1.4.0 (skipped minor version)
# - 1.2.3 → 1.2.0 (went backwards)
# - 1.2.3 → 1.3.1 (didn't reset patch)
#
- name: Check VERSION was bumped (semantic versioning)
if: github.event_name == 'pull_request'
run: |
# Get VERSION from this PR branch
PR_VERSION=$(cat VERSION 2>/dev/null || echo "0.0.0")
# Get VERSION from main branch
git fetch origin main:main
MAIN_VERSION=$(git show main:VERSION 2>/dev/null || echo "0.0.0")
echo "📋 Semantic Version Check"
echo "Main branch version: $MAIN_VERSION"
echo "PR branch version: $PR_VERSION"
echo ""
# Parse versions into components
IFS='.' read -r MAIN_MAJOR MAIN_MINOR MAIN_PATCH <<< "$MAIN_VERSION"
IFS='.' read -r PR_MAJOR PR_MINOR PR_PATCH <<< "$PR_VERSION"
# Remove any non-numeric characters
MAIN_MAJOR=${MAIN_MAJOR//[!0-9]/}
MAIN_MINOR=${MAIN_MINOR//[!0-9]/}
MAIN_PATCH=${MAIN_PATCH//[!0-9]/}
PR_MAJOR=${PR_MAJOR//[!0-9]/}
PR_MINOR=${PR_MINOR//[!0-9]/}
PR_PATCH=${PR_PATCH//[!0-9]/}
# Check if VERSION unchanged
if [ "$PR_VERSION" = "$MAIN_VERSION" ]; then
echo "❌ ERROR: VERSION file has not been updated!"
echo ""
echo "Please update the VERSION file in your PR."
echo "Current version: $MAIN_VERSION"
exit 1
fi
# Validate semantic version bump
VALID=false
BUMP_TYPE=""
# Check for major version bump (X.0.0)
if [ "$PR_MAJOR" -eq $((MAIN_MAJOR + 1)) ] && [ "$PR_MINOR" -eq 0 ] && [ "$PR_PATCH" -eq 0 ]; then
VALID=true
BUMP_TYPE="major"
# Check for minor version bump (x.X.0)
elif [ "$PR_MAJOR" -eq "$MAIN_MAJOR" ] && [ "$PR_MINOR" -eq $((MAIN_MINOR + 1)) ] && [ "$PR_PATCH" -eq 0 ]; then
VALID=true
BUMP_TYPE="minor"
# Check for patch version bump (x.x.X)
elif [ "$PR_MAJOR" -eq "$MAIN_MAJOR" ] && [ "$PR_MINOR" -eq "$MAIN_MINOR" ] && [ "$PR_PATCH" -eq $((MAIN_PATCH + 1)) ]; then
VALID=true
BUMP_TYPE="patch"
fi
if [ "$VALID" = true ]; then
echo "✅ Valid $BUMP_TYPE version bump: $MAIN_VERSION → $PR_VERSION"
else
echo "❌ ERROR: Invalid semantic version change!"
echo ""
echo "Current version: $MAIN_VERSION"
echo "PR version: $PR_VERSION"
echo ""
echo "Valid version bumps:"
echo " - Patch: $MAIN_MAJOR.$MAIN_MINOR.$((MAIN_PATCH + 1))"
echo " - Minor: $MAIN_MAJOR.$((MAIN_MINOR + 1)).0"
echo " - Major: $((MAIN_MAJOR + 1)).0.0"
echo ""
echo "Common issues:"
echo " ❌ Skipping versions (e.g., 2.5.0 → 2.7.0)"
echo " ❌ Going backwards (e.g., 2.5.0 → 2.4.0)"
echo " ❌ Not resetting lower components (e.g., 2.5.0 → 2.6.1)"
exit 1
fi
# ==============================================
# 3. DOCKER BUILDX SETUP
# ==============================================
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# ==============================================
# 4. DOCKER HUB LOGIN (main branch only)
# ==============================================
# Requires secrets in Gitea:
# - DOCKERHUB_USERNAME: Your Docker Hub username
# - DOCKERHUB_TOKEN: Docker Hub access token (not password!)
#
# To create token:
# 1. Go to hub.docker.com
# 2. Account Settings → Security → New Access Token
# 3. Copy token to Gitea repo → Settings → Secrets → Actions
#
- name: Login to Docker Hub
if: github.ref == 'refs/heads/main'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# ==============================================
# 5. EXTRACT METADATA
# ==============================================
# Reads VERSION file and generates image tags:
# - version: From VERSION file (e.g., "1.2.3")
# - sha_short: First 7 chars of commit SHA
# - version_sha: Combined version+commit (e.g., "v1.2.3-a1b2c3d")
# - branch: Current branch name
# - timestamp: ISO 8601 format for Discord
#
- name: Extract metadata
id: meta
run: |
VERSION=$(cat VERSION 2>/dev/null || echo "0.0.0")
SHA_SHORT=$(echo ${{ github.sha }} | cut -c1-7)
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "sha_short=${SHA_SHORT}" >> $GITHUB_OUTPUT
echo "version_sha=v${VERSION}-${SHA_SHORT}" >> $GITHUB_OUTPUT
echo "branch=${{ github.ref_name }}" >> $GITHUB_OUTPUT
echo "timestamp=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
# ==============================================
# 6. BUILD AND PUSH DOCKER IMAGE
# ==============================================
# Creates 3 tags for each build:
# - latest: Always points to newest build
# - v{VERSION}: Semantic version from VERSION file
# - v{VERSION}-{COMMIT}: Version + commit hash for traceability
#
# Example tags:
# - manticorum67/paper-dynasty-database:latest
# - manticorum67/paper-dynasty-database:v1.5.5
# - manticorum67/paper-dynasty-database:v1.5.5-a1b2c3d
#
# Push behavior:
# - PRs: Build only (test), don't push
# - Main: Build and push to Docker Hub
#
- name: Build Docker image
uses: docker/build-push-action@v5
with:
context: .
push: ${{ github.ref == 'refs/heads/main' }}
tags: |
manticorum67/paper-dynasty-database:latest
manticorum67/paper-dynasty-database:v${{ steps.meta.outputs.version }}
manticorum67/paper-dynasty-database:${{ steps.meta.outputs.version_sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
# ==============================================
# 7. BUILD SUMMARY
# ==============================================
# Creates a formatted summary visible in Actions UI
# Shows: image tags, build details, push status
#
- name: Build Summary
run: |
echo "## 🐳 Docker Build Successful! ✅" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Image Tags:**" >> $GITHUB_STEP_SUMMARY
echo "- \`manticorum67/paper-dynasty-database:latest\`" >> $GITHUB_STEP_SUMMARY
echo "- \`manticorum67/paper-dynasty-database:v${{ steps.meta.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
echo "- \`manticorum67/paper-dynasty-database:${{ steps.meta.outputs.version_sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Build Details:**" >> $GITHUB_STEP_SUMMARY
echo "- Branch: \`${{ steps.meta.outputs.branch }}\`" >> $GITHUB_STEP_SUMMARY
echo "- Commit: \`${{ github.sha }}\`" >> $GITHUB_STEP_SUMMARY
echo "- Timestamp: \`${{ steps.meta.outputs.timestamp }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${{ github.ref }}" == "refs/heads/main" ]; then
echo "🚀 **Pushed to Docker Hub!**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Pull with: \`docker pull manticorum67/paper-dynasty-database:latest\`" >> $GITHUB_STEP_SUMMARY
else
echo "_PR build - image not pushed to Docker Hub_" >> $GITHUB_STEP_SUMMARY
fi
# ==============================================
# 8. DISCORD NOTIFICATION - SUCCESS
# ==============================================
# Sends green embed to Discord on successful builds
#
# Only fires on main branch pushes (not PRs)
#
# Setup:
# 1. Create webhook in Discord channel:
# Right-click channel → Edit → Integrations → Webhooks → New
# 2. Copy webhook URL
# 3. Add to Gitea: Settings → Secrets → Actions → DISCORD_WEBHOOK
#
- name: Discord Notification - Success
if: success() && github.ref == 'refs/heads/main'
run: |
curl -H "Content-Type: application/json" \
-d '{
"embeds": [{
"title": "✅ Paper Dynasty Database Build Successful",
"description": "Docker image built and pushed to Docker Hub!",
"color": 3066993,
"fields": [
{
"name": "Version",
"value": "`v${{ steps.meta.outputs.version }}`",
"inline": true
},
{
"name": "Image Tag",
"value": "`${{ steps.meta.outputs.version_sha }}`",
"inline": true
},
{
"name": "Branch",
"value": "`${{ steps.meta.outputs.branch }}`",
"inline": true
},
{
"name": "Commit",
"value": "`${{ steps.meta.outputs.sha_short }}`",
"inline": true
},
{
"name": "Author",
"value": "${{ github.actor }}",
"inline": true
},
{
"name": "Docker Hub",
"value": "[manticorum67/paper-dynasty-database](https://hub.docker.com/r/manticorum67/paper-dynasty-database)",
"inline": false
},
{
"name": "View Run",
"value": "[Click here](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})",
"inline": false
}
],
"timestamp": "${{ steps.meta.outputs.timestamp }}"
}]
}' \
${{ secrets.DISCORD_WEBHOOK }}
# ==============================================
# 9. DISCORD NOTIFICATION - FAILURE
# ==============================================
# Sends red embed to Discord on build failures
#
# Only fires on main branch pushes (not PRs)
#
- name: Discord Notification - Failure
if: failure() && github.ref == 'refs/heads/main'
run: |
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
curl -H "Content-Type: application/json" \
-d '{
"embeds": [{
"title": "❌ Paper Dynasty Database Build Failed",
"description": "Docker build encountered an error.",
"color": 15158332,
"fields": [
{
"name": "Branch",
"value": "`${{ github.ref_name }}`",
"inline": true
},
{
"name": "Commit",
"value": "`${{ github.sha }}`",
"inline": true
},
{
"name": "Author",
"value": "${{ github.actor }}",
"inline": true
},
{
"name": "View Logs",
"value": "[Click here](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})",
"inline": false
}
],
"timestamp": "'"$TIMESTAMP"'"
}]
}' \
${{ secrets.DISCORD_WEBHOOK }}
# ==============================================
# SETUP CHECKLIST
# ==============================================
# Before this workflow will work:
#
# ✅ Add secrets to Gitea repo (Settings → Secrets → Actions):
# - DOCKERHUB_USERNAME: Your Docker Hub username (manticorum67)
# - DOCKERHUB_TOKEN: Docker Hub access token
# - DISCORD_WEBHOOK: Discord webhook URL for notifications
#
# ✅ Ensure VERSION file exists in repo root (currently at 1.5.5)
#
# ✅ Update branch name if not using "main"
#
# ==============================================
# TROUBLESHOOTING
# ==============================================
# Common issues and solutions:
#
# 1. VERSION validation failing unexpectedly
# - Ensure VERSION file exists in repo root
# - Check file contains only version number (no 'v' prefix or extra text)
# - Verify version follows semver: MAJOR.MINOR.PATCH
#
# 2. Docker Hub push failing
# - Verify DOCKERHUB_USERNAME and DOCKERHUB_TOKEN secrets are set
# - Check Docker Hub token has push permissions
# - Ensure repository name matches your Docker Hub repo exactly
#
# 3. Discord notifications not appearing
# - Verify DISCORD_WEBHOOK secret is set in Gitea
# - Test webhook URL manually with curl
# - Check webhook still exists in Discord channel settings
#
# 4. Build cache not working
# - GitHub Actions cache is stored per repository
# - Cache is shared across branches
# - May need to clear cache if corrupted
#
# ==============================================

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
1.5.4 1.5.5

View File

@ -116,6 +116,7 @@ CARDSETS = {
"gauntlet-9": { "gauntlet-9": {
"primary": [27], # 2005 "primary": [27], # 2005
"secondary": [24], # 2025 "secondary": [24], # 2025
"human": [x for x in range(1, 30)],
}, },
} }

View File

@ -1,898 +0,0 @@
import math
"""
DEPRECATED: This file is a legacy implementation from before the deployment
of /database/app/. The active codebase is now in /database/app/db_engine.py.
This file is kept for reference only and should not be used.
"""
from datetime import datetime
from typing import List
import logging
import os
from pandas import DataFrame
from peewee import *
from peewee import ModelSelect
from playhouse.shortcuts import model_to_dict
db = SqliteDatabase(
"storage/pd_master.db",
pragmas={"journal_mode": "wal", "cache_size": -1 * 64000, "synchronous": 0},
)
date = f"{datetime.now().year}-{datetime.now().month}-{datetime.now().day}"
log_level = logging.INFO if os.environ.get("LOG_LEVEL") == "INFO" else "WARN"
logging.basicConfig(
filename=f"logs/database/{date}.log",
format="%(asctime)s - database - %(levelname)s - %(message)s",
level=log_level,
)
def model_csv_headers(this_obj, exclude=None) -> List:
data = model_to_dict(this_obj, recurse=False, exclude=exclude)
return [x for x in data.keys()]
def model_to_csv(this_obj, exclude=None) -> List:
data = model_to_dict(this_obj, recurse=False, exclude=exclude)
return [x for x in data.values()]
def query_to_csv(all_items: ModelSelect, exclude=None):
if all_items.count() == 0:
data_list = [["No data found"]]
else:
data_list = [model_csv_headers(all_items[0], exclude=exclude)]
for x in all_items:
data_list.append(model_to_csv(x, exclude=exclude))
return DataFrame(data_list).to_csv(header=False, index=False)
def complex_data_to_csv(complex_data: List):
if len(complex_data) == 0:
data_list = [["No data found"]]
else:
data_list = [[x for x in complex_data[0].keys()]]
for line in complex_data:
logging.debug(f"line: {line}")
this_row = []
for key in line:
logging.debug(f"key: {key}")
if line[key] is None:
this_row.append("")
elif isinstance(line[key], dict):
if "name" in line[key]:
this_row.append(line[key]["name"])
elif "abbrev" in line[key]:
this_row.append(line[key]["abbrev"])
else:
this_row.append(line[key]["id"])
elif isinstance(line[key], int) and line[key] > 100000000:
this_row.append(f"'{line[key]}")
elif isinstance(line[key], str) and "," in line[key]:
this_row.append(line[key].replace(",", "-_-"))
else:
this_row.append(line[key])
data_list.append(this_row)
return DataFrame(data_list).to_csv(header=False, index=False)
class BaseModel(Model):
class Meta:
database = db
class Current(BaseModel):
season = IntegerField()
week = IntegerField(default=0)
gsheet_template = CharField()
gsheet_version = CharField()
live_scoreboard = IntegerField()
@staticmethod
def latest():
latest_current = Current.select().order_by(-Current.id).get()
return latest_current
db.create_tables([Current])
class Rarity(BaseModel):
value = IntegerField()
name = CharField(unique=True)
color = CharField()
def __str__(self):
return self.name
db.create_tables([Rarity])
class Event(BaseModel):
name = CharField()
short_desc = CharField(null=True)
url = CharField(null=True)
long_desc = CharField(null=True)
thumbnail = CharField(null=True)
active = BooleanField(default=False)
db.create_tables([Event])
class Cardset(BaseModel):
name = CharField()
description = CharField()
event = ForeignKeyField(Event, null=True)
for_purchase = BooleanField(default=True) # for_purchase
total_cards = IntegerField()
in_packs = BooleanField(default=True)
ranked_legal = BooleanField(default=True)
def __str__(self):
return self.name
db.create_tables([Cardset])
class MlbPlayer(BaseModel):
first_name = CharField()
last_name = CharField()
key_fangraphs = IntegerField(null=True)
key_bbref = CharField(null=True)
key_retro = CharField(null=True)
key_mlbam = IntegerField(null=True)
offense_col = IntegerField(default=1)
db.create_tables([MlbPlayer])
class Player(BaseModel):
player_id = IntegerField(primary_key=True)
p_name = CharField()
cost = IntegerField(default=0)
image = CharField()
image2 = CharField(null=True)
mlbclub = CharField()
franchise = CharField()
cardset = ForeignKeyField(Cardset)
set_num = IntegerField()
rarity = ForeignKeyField(Rarity)
pos_1 = CharField()
pos_2 = CharField(null=True)
pos_3 = CharField(null=True)
pos_4 = CharField(null=True)
pos_5 = CharField(null=True)
pos_6 = CharField(null=True)
pos_7 = CharField(null=True)
pos_8 = CharField(null=True)
headshot = CharField(null=True)
vanity_card = CharField(null=True)
strat_code = CharField(null=True)
bbref_id = CharField(null=True)
fangr_id = CharField(null=True)
description = CharField()
quantity = IntegerField(default=999)
mlbplayer = ForeignKeyField(MlbPlayer, null=True)
def __str__(self):
return f"{self.cardset} {self.p_name} ({self.rarity.name})"
# def __eq__(self, other):
# if self.cardset.id == other.cardset.id and self.name == other.name:
# return True
# else:
# return False
def __lt__(self, other):
if self.wara < other.wara:
return True
elif self.wara > other.wara:
return False
elif self.name < other.name:
return True
else:
return False
def get_all_pos(self):
all_pos = []
if self.pos_1 and self.pos_1 != "CP":
all_pos.append(self.pos_1)
if self.pos_2 and self.pos_2 != "CP":
all_pos.append(self.pos_2)
if self.pos_3 and self.pos_3 != "CP":
all_pos.append(self.pos_3)
if self.pos_4 and self.pos_4 != "CP":
all_pos.append(self.pos_4)
if self.pos_5 and self.pos_5 != "CP":
all_pos.append(self.pos_5)
if self.pos_6 and self.pos_6 != "CP":
all_pos.append(self.pos_6)
if self.pos_7 and self.pos_7 != "CP":
all_pos.append(self.pos_7)
if self.pos_8 and self.pos_8 != "CP":
all_pos.append(self.pos_8)
return all_pos
def change_on_sell(self):
# caps = {
# 'replacement': 15,
# 'reserve': 50,
# 'starter': 200,
# 'all-star': 750,
# 'mvp': 2500,
# 'hof': 999999999
# }
logging.info(f"{self.p_name} cost changing from: {self.cost}")
self.cost = max(math.floor(self.cost * 0.95), 1)
# if self.quantity != 999:
# self.quantity += 1
logging.info(f"{self.p_name} cost now: {self.cost}")
self.save()
def change_on_buy(self):
logging.info(f"{self.p_name} cost changing from: {self.cost}")
self.cost = math.ceil(self.cost * 1.1)
# if self.quantity != 999:
# self.quantity -= 1
logging.info(f"{self.p_name} cost now: {self.cost}")
self.save()
db.create_tables([Player])
class Team(BaseModel):
abbrev = CharField()
sname = CharField()
lname = CharField()
gmid = IntegerField()
gmname = CharField()
gsheet = CharField()
wallet = IntegerField()
team_value = IntegerField()
collection_value = IntegerField()
logo = CharField(null=True)
color = CharField(null=True)
season = IntegerField()
event = ForeignKeyField(Event, null=True)
career = IntegerField(default=0)
ranking = IntegerField(default=1000)
has_guide = BooleanField(default=False)
is_ai = IntegerField(null=True)
def __str__(self):
return f"S{self.season} {self.lname}"
@staticmethod
def get_by_owner(gmid, season=None):
if not season:
season = Current.get().season
team = Team.get_or_none((Team.gmid == gmid) & (Team.season == season))
if not team:
return None
return team
@staticmethod
def select_season(season=None):
if not season:
season = Current.get().season
return Team.select().where(Team.season == season)
@staticmethod
def get_season(abbrev, season=None):
if not season:
season = Current.get().season
return Team.get_or_none(Team.season == season, Team.abbrev == abbrev.upper())
def team_hash(self):
hash_string = f"{self.sname[-1]}{self.gmid / 6950123:.0f}{self.sname[-2]}{self.gmid / 42069123:.0f}"
logging.info(f"string: {hash_string}")
return hash_string
db.create_tables([Team])
class PackType(BaseModel):
name = CharField()
card_count = IntegerField()
description = CharField()
cost = IntegerField()
available = BooleanField(default=True)
db.create_tables([PackType])
class Pack(BaseModel):
team = ForeignKeyField(Team)
pack_type = ForeignKeyField(PackType)
pack_team = ForeignKeyField(Team, null=True)
pack_cardset = ForeignKeyField(Cardset, null=True)
open_time = DateTimeField(null=True)
db.create_tables([Pack])
class Card(BaseModel):
player = ForeignKeyField(Player, null=True)
team = ForeignKeyField(Team, null=True)
pack = ForeignKeyField(Pack, null=True)
value = IntegerField(default=0)
def __str__(self):
if self.player:
return f"{self.player} - {self.team.sname}"
else:
return f"Blank - {self.team.sname}"
@staticmethod
def select_season(season):
return Card.select().join(Team).where(Card.team.season == season)
db.create_tables([Card])
class Roster(BaseModel):
team = ForeignKeyField(Team)
name = CharField()
roster_num = IntegerField()
card_1 = ForeignKeyField(Card)
card_2 = ForeignKeyField(Card)
card_3 = ForeignKeyField(Card)
card_4 = ForeignKeyField(Card)
card_5 = ForeignKeyField(Card)
card_6 = ForeignKeyField(Card)
card_7 = ForeignKeyField(Card)
card_8 = ForeignKeyField(Card)
card_9 = ForeignKeyField(Card)
card_10 = ForeignKeyField(Card)
card_11 = ForeignKeyField(Card)
card_12 = ForeignKeyField(Card)
card_13 = ForeignKeyField(Card)
card_14 = ForeignKeyField(Card)
card_15 = ForeignKeyField(Card)
card_16 = ForeignKeyField(Card)
card_17 = ForeignKeyField(Card)
card_18 = ForeignKeyField(Card)
card_19 = ForeignKeyField(Card)
card_20 = ForeignKeyField(Card)
card_21 = ForeignKeyField(Card)
card_22 = ForeignKeyField(Card)
card_23 = ForeignKeyField(Card)
card_24 = ForeignKeyField(Card)
card_25 = ForeignKeyField(Card)
card_26 = ForeignKeyField(Card)
def __str__(self):
return f"{self.team} Roster"
# def get_cards(self, team):
# all_cards = Card.select().where(Card.roster == self)
# this_roster = []
# return [this_roster.card1, this_roster.card2, this_roster.card3, this_roster.card4, this_roster.card5,
# this_roster.card6, this_roster.card7, this_roster.card8, this_roster.card9, this_roster.card10,
# this_roster.card11, this_roster.card12, this_roster.card13, this_roster.card14, this_roster.card15,
# this_roster.card16, this_roster.card17, this_roster.card18, this_roster.card19, this_roster.card20,
# this_roster.card21, this_roster.card22, this_roster.card23, this_roster.card24, this_roster.card25,
# this_roster.card26]
class Result(BaseModel):
away_team = ForeignKeyField(Team)
home_team = ForeignKeyField(Team)
away_score = IntegerField()
home_score = IntegerField()
away_team_value = IntegerField(null=True)
home_team_value = IntegerField(null=True)
away_team_ranking = IntegerField(null=True)
home_team_ranking = IntegerField(null=True)
scorecard = CharField()
week = IntegerField()
season = IntegerField()
ranked = BooleanField()
short_game = BooleanField()
game_type = CharField(null=True)
@staticmethod
def select_season(season=None):
if not season:
season = Current.get().season
return Result.select().where(Result.season == season)
class BattingStat(BaseModel):
card = ForeignKeyField(Card)
team = ForeignKeyField(Team)
roster_num = IntegerField()
vs_team = ForeignKeyField(Team)
result = ForeignKeyField(Result, null=True)
pos = CharField()
pa = IntegerField()
ab = IntegerField()
run = IntegerField()
hit = IntegerField()
rbi = IntegerField()
double = IntegerField()
triple = IntegerField()
hr = IntegerField()
bb = IntegerField()
so = IntegerField()
hbp = IntegerField()
sac = IntegerField()
ibb = IntegerField()
gidp = IntegerField()
sb = IntegerField()
cs = IntegerField()
bphr = IntegerField()
bpfo = IntegerField()
bp1b = IntegerField()
bplo = IntegerField()
xch = IntegerField()
xhit = IntegerField()
error = IntegerField()
pb = IntegerField()
sbc = IntegerField()
csc = IntegerField()
week = IntegerField()
season = IntegerField()
created = DateTimeField()
game_id = IntegerField()
class PitchingStat(BaseModel):
card = ForeignKeyField(Card)
team = ForeignKeyField(Team)
roster_num = IntegerField()
vs_team = ForeignKeyField(Team)
result = ForeignKeyField(Result, null=True)
ip = FloatField()
hit = IntegerField()
run = IntegerField()
erun = IntegerField()
so = IntegerField()
bb = IntegerField()
hbp = IntegerField()
wp = IntegerField()
balk = IntegerField()
hr = IntegerField()
ir = IntegerField()
irs = IntegerField()
gs = IntegerField()
win = IntegerField()
loss = IntegerField()
hold = IntegerField()
sv = IntegerField()
bsv = IntegerField()
week = IntegerField()
season = IntegerField()
created = DateTimeField()
game_id = IntegerField()
class Award(BaseModel):
name = CharField()
season = IntegerField()
timing = CharField(default="In-Season")
card = ForeignKeyField(Card, null=True)
team = ForeignKeyField(Team, null=True)
image = CharField(null=True)
class Paperdex(BaseModel):
team = ForeignKeyField(Team)
player = ForeignKeyField(Player)
created = DateTimeField(default=datetime.now)
# def add_to_paperdex(self, team, cards: list):
# for x in players:
# if not isinstance(x, Card):
# raise TypeError(f'The Pokedex can only take a list of Player or Card objects')
#
# Paperdex.get_or_create(team=team, player=player)
class Reward(BaseModel):
name = CharField(null=True)
season = IntegerField()
week = IntegerField()
team = ForeignKeyField(Team)
created = DateTimeField()
class GameRewards(BaseModel):
name = CharField()
pack_type = ForeignKeyField(PackType, null=True)
player = ForeignKeyField(Player, null=True)
money = IntegerField(null=True)
class Notification(BaseModel):
created = DateTimeField()
title = CharField()
desc = CharField(null=True)
field_name = CharField()
message = CharField()
about = CharField() # f'{Topic}-{Object ID}'
ack = BooleanField(default=False)
class GauntletReward(BaseModel):
name = CharField()
gauntlet = ForeignKeyField(Event)
reward = ForeignKeyField(GameRewards)
win_num = IntegerField()
loss_max = IntegerField(default=1)
class GauntletRun(BaseModel):
team = ForeignKeyField(Team)
gauntlet = ForeignKeyField(Event)
wins = IntegerField(default=0)
losses = IntegerField(default=0)
gsheet = CharField(null=True)
created = DateTimeField(default=datetime.now)
ended = DateTimeField(null=True)
db.create_tables(
[
Roster,
BattingStat,
PitchingStat,
Result,
Award,
Paperdex,
Reward,
GameRewards,
Notification,
GauntletReward,
GauntletRun,
]
)
class BattingCard(BaseModel):
player = ForeignKeyField(Player)
variant = IntegerField()
steal_low = IntegerField()
steal_high = IntegerField()
steal_auto = BooleanField()
steal_jump = FloatField()
bunting = CharField()
hit_and_run = CharField()
running = IntegerField()
offense_col = IntegerField()
hand = CharField(default="R")
bc_index = ModelIndex(
BattingCard, (BattingCard.player, BattingCard.variant), unique=True
)
BattingCard.add_index(bc_index)
class BattingCardRatings(BaseModel):
battingcard = ForeignKeyField(BattingCard)
vs_hand = CharField(default="R")
pull_rate = FloatField()
center_rate = FloatField()
slap_rate = FloatField()
homerun = FloatField()
bp_homerun = FloatField()
triple = FloatField()
double_three = FloatField()
double_two = FloatField()
double_pull = FloatField()
single_two = FloatField()
single_one = FloatField()
single_center = FloatField()
bp_single = FloatField()
hbp = FloatField()
walk = FloatField()
strikeout = FloatField()
lineout = FloatField()
popout = FloatField()
flyout_a = FloatField()
flyout_bq = FloatField()
flyout_lf_b = FloatField()
flyout_rf_b = FloatField()
groundout_a = FloatField()
groundout_b = FloatField()
groundout_c = FloatField()
avg = FloatField(null=True)
obp = FloatField(null=True)
slg = FloatField(null=True)
bcr_index = ModelIndex(
BattingCardRatings,
(BattingCardRatings.battingcard, BattingCardRatings.vs_hand),
unique=True,
)
BattingCardRatings.add_index(bcr_index)
class PitchingCard(BaseModel):
player = ForeignKeyField(Player)
variant = IntegerField()
balk = IntegerField()
wild_pitch = IntegerField()
hold = IntegerField()
starter_rating = IntegerField()
relief_rating = IntegerField()
closer_rating = IntegerField(null=True)
batting = CharField(null=True)
offense_col = IntegerField()
hand = CharField(default="R")
pc_index = ModelIndex(
PitchingCard, (PitchingCard.player, PitchingCard.variant), unique=True
)
PitchingCard.add_index(pc_index)
class PitchingCardRatings(BaseModel):
pitchingcard = ForeignKeyField(PitchingCard)
vs_hand = CharField(default="R")
homerun = FloatField()
bp_homerun = FloatField()
triple = FloatField()
double_three = FloatField()
double_two = FloatField()
double_cf = FloatField()
single_two = FloatField()
single_one = FloatField()
single_center = FloatField()
bp_single = FloatField()
hbp = FloatField()
walk = FloatField()
strikeout = FloatField()
flyout_lf_b = FloatField()
flyout_cf_b = FloatField()
flyout_rf_b = FloatField()
groundout_a = FloatField()
groundout_b = FloatField()
xcheck_p = FloatField()
xcheck_c = FloatField()
xcheck_1b = FloatField()
xcheck_2b = FloatField()
xcheck_3b = FloatField()
xcheck_ss = FloatField()
xcheck_lf = FloatField()
xcheck_cf = FloatField()
xcheck_rf = FloatField()
avg = FloatField(null=True)
obp = FloatField(null=True)
slg = FloatField(null=True)
pcr_index = ModelIndex(
PitchingCardRatings,
(PitchingCardRatings.pitchingcard, PitchingCardRatings.vs_hand),
unique=True,
)
PitchingCardRatings.add_index(pcr_index)
class CardPosition(BaseModel):
player = ForeignKeyField(Player)
variant = IntegerField()
position = CharField()
innings = IntegerField()
range = IntegerField()
error = IntegerField()
arm = IntegerField(null=True)
pb = IntegerField(null=True)
overthrow = IntegerField(null=True)
pos_index = ModelIndex(
CardPosition,
(CardPosition.player, CardPosition.variant, CardPosition.position),
unique=True,
)
CardPosition.add_index(pos_index)
db.create_tables(
[BattingCard, BattingCardRatings, PitchingCard, PitchingCardRatings, CardPosition]
)
db.close()
# scout_db = SqliteDatabase(
# 'storage/card_creation.db',
# pragmas={
# 'journal_mode': 'wal',
# 'cache_size': -1 * 64000,
# 'synchronous': 0
# }
# )
#
#
# class BaseModelScout(Model):
# class Meta:
# database = scout_db
#
#
# class ScoutCardset(BaseModelScout):
# set_title = CharField()
# set_subtitle = CharField(null=True)
#
#
# class ScoutPlayer(BaseModelScout):
# sba_id = IntegerField(primary_key=True)
# name = CharField()
# fg_id = IntegerField()
# br_id = CharField()
# offense_col = IntegerField()
# hand = CharField(default='R')
#
#
# scout_db.create_tables([ScoutCardset, ScoutPlayer])
#
#
# class BatterRatings(BaseModelScout):
# id = CharField(unique=True, primary_key=True)
# player = ForeignKeyField(ScoutPlayer)
# cardset = ForeignKeyField(ScoutCardset)
# vs_hand = FloatField()
# is_prep = BooleanField()
# homerun = FloatField()
# bp_homerun = FloatField()
# triple = FloatField()
# double_three = FloatField()
# double_two = FloatField()
# double_pull = FloatField()
# single_two = FloatField()
# single_one = FloatField()
# single_center = FloatField()
# bp_single = FloatField()
# hbp = FloatField()
# walk = FloatField()
# strikeout = FloatField()
# lineout = FloatField()
# popout = FloatField()
# flyout_a = FloatField()
# flyout_bq = FloatField()
# flyout_lf_b = FloatField()
# flyout_rf_b = FloatField()
# groundout_a = FloatField()
# groundout_b = FloatField()
# groundout_c = FloatField()
# avg = FloatField(null=True)
# obp = FloatField(null=True)
# slg = FloatField(null=True)
#
#
# class PitcherRatings(BaseModelScout):
# id = CharField(unique=True, primary_key=True)
# player = ForeignKeyField(ScoutPlayer)
# cardset = ForeignKeyField(ScoutCardset)
# vs_hand = CharField()
# is_prep = BooleanField()
# homerun = FloatField()
# bp_homerun = FloatField()
# triple = FloatField()
# double_three = FloatField()
# double_two = FloatField()
# double_cf = FloatField()
# single_two = FloatField()
# single_one = FloatField()
# single_center = FloatField()
# bp_single = FloatField()
# hbp = FloatField()
# walk = FloatField()
# strikeout = FloatField()
# fo_slap = FloatField()
# fo_center = FloatField()
# groundout_a = FloatField()
# groundout_b = FloatField()
# xcheck_p = FloatField()
# xcheck_c = FloatField()
# xcheck_1b = FloatField()
# xcheck_2b = FloatField()
# xcheck_3b = FloatField()
# xcheck_ss = FloatField()
# xcheck_lf = FloatField()
# xcheck_cf = FloatField()
# xcheck_rf = FloatField()
# avg = FloatField(null=True)
# obp = FloatField(null=True)
# slg = FloatField(null=True)
#
#
# # scout_db.create_tables([BatterRatings, PitcherRatings])
#
#
# class CardColumns(BaseModelScout):
# id = CharField(unique=True, primary_key=True)
# player = ForeignKeyField(ScoutPlayer)
# hand = CharField()
# b_ratings = ForeignKeyField(BatterRatings, null=True)
# p_ratings = ForeignKeyField(PitcherRatings, null=True)
# one_dice = CharField()
# one_results = CharField()
# one_splits = CharField()
# two_dice = CharField()
# two_results = CharField()
# two_splits = CharField()
# three_dice = CharField()
# three_results = CharField()
# three_splits = CharField()
#
#
# class Position(BaseModelScout):
# player = ForeignKeyField(ScoutPlayer)
# cardset = ForeignKeyField(ScoutCardset)
# position = CharField()
# innings = IntegerField()
# range = IntegerField()
# error = IntegerField()
# arm = CharField(null=True)
# pb = IntegerField(null=True)
# overthrow = IntegerField(null=True)
#
#
# class BatterData(BaseModelScout):
# player = ForeignKeyField(ScoutPlayer)
# cardset = ForeignKeyField(ScoutCardset)
# stealing = CharField()
# st_low = IntegerField()
# st_high = IntegerField()
# st_auto = BooleanField()
# st_jump = FloatField()
# bunting = CharField(null=True)
# hit_and_run = CharField(null=True)
# running = CharField()
#
#
# class PitcherData(BaseModelScout):
# player = ForeignKeyField(ScoutPlayer)
# cardset = ForeignKeyField(ScoutCardset)
# balk = IntegerField(null=True)
# wild_pitch = IntegerField(null=True)
# hold = CharField()
# starter_rating = IntegerField()
# relief_rating = IntegerField()
# closer_rating = IntegerField(null=True)
# batting = CharField(null=True)
#
#
# scout_db.create_tables([CardColumns, Position, BatterData, PitcherData])
#
#
# class CardOutput(BaseModelScout):
# name = CharField()
# hand = CharField()
# positions = CharField()
# stealing = CharField()
# bunting = CharField()
# hitandrun = CharField()
# running = CharField()
#
#
# scout_db.close()

View File

@ -1,50 +0,0 @@
from playhouse.migrate import *
import db_engine
# Automatically select correct migrator based on database type
if hasattr(db_engine.db, '__class__') and 'Postgres' in db_engine.db.__class__.__name__:
migrator = PostgresqlMigrator(db_engine.db)
else:
migrator = SqliteMigrator(db_engine.db)
# db_engine.db.create_tables([db_engine.PackTheme])
# pubdate_field = DateTimeField(null=True)
# comment_field = TextField(default='')
# pitcher_injury = IntegerField(null=True)
# offense_col = IntegerField(null=True)
# pos_2 = CharField(null=True)
# last_game = CharField(null=True)
# game_type = CharField(null=True)
mlb_player = ForeignKeyField(db_engine.MlbPlayer, field=db_engine.MlbPlayer.id, null=True)
result = ForeignKeyField(db_engine.Result, field=db_engine.Result.id, null=True)
# active_theme = ForeignKeyField(PackTheme, to_field='id', field_type=int, null=True)
# active_theme = ForeignKeyField(db_engine.PackTheme, field=db_engine.PackTheme.id, null=True) # for careers
# game_type = CharField(null=True)
# pack_team = ForeignKeyField(db_engine.Team, field=db_engine.Team.id, null=True)
# pack_cardset = ForeignKeyField(db_engine.Cardset, field=db_engine.Cardset.id, null=True)
pull_rate = FloatField(default=0.333)
migrate(
# migrator.add_column('current', 'active_theme_id', active_theme),
# migrator.add_column('pack', 'pack_team_id', pack_team),
# migrator.add_column('player', 'mlbplayer_id', mlb_player),
migrator.add_column('battingstat', 'result_id', result),
migrator.add_column('pitchingstat', 'result_id', result),
# migrator.add_column('battingcardratings', 'pull_rate', pull_rate),
# migrator.rename_column('cardset', 'available', 'for_purchase')
# migrator.add_column('player', 'offense_col', offense_col),
# migrator.add_column('comment_tbl', 'comment', comment_field),
# migrator.rename_column('story', 'pub_date', 'publish_date'),
# migrator.drop_column('story', 'some_old_field'),
# migrator.drop_not_null('team', 'abbrev'),
# migrator.add_not_null('story', 'modified_date'),
# migrator.rename_table('story', 'stories_tbl'),
# migrator.drop_index('team', 'team_abbrev'),
# migrator.drop_index('player', 'player_name')
# migrator.add_column('pack', 'pack_type', pack_type),
)
db_engine.db.close()

6363
main.py

File diff suppressed because it is too large Load Diff

View File

@ -1,104 +0,0 @@
-- Migration: Normalize Player.franchise to city-agnostic values
-- Date: 2026-01-07
-- Purpose: Enable cross-era player matching for AI rosters by normalizing
-- franchise values to match Team.sname (e.g., 'Oakland Athletics' -> 'Athletics')
--
-- IMPORTANT: Backup database before running!
-- Run on dev first, verify with: SELECT DISTINCT franchise FROM player ORDER BY franchise;
-- Then run on prod.
--
-- Rollback: See inverse statements at bottom of file
-- ============================================
-- FORWARD MIGRATION: Normalize franchise values
-- ============================================
-- National League West
UPDATE player SET franchise = 'Diamondbacks' WHERE franchise = 'Arizona Diamondbacks';
UPDATE player SET franchise = 'Rockies' WHERE franchise = 'Colorado Rockies';
UPDATE player SET franchise = 'Dodgers' WHERE franchise = 'Los Angeles Dodgers';
UPDATE player SET franchise = 'Padres' WHERE franchise = 'San Diego Padres';
UPDATE player SET franchise = 'Giants' WHERE franchise = 'San Francisco Giants';
-- National League Central
UPDATE player SET franchise = 'Cubs' WHERE franchise = 'Chicago Cubs';
UPDATE player SET franchise = 'Reds' WHERE franchise = 'Cincinnati Reds';
UPDATE player SET franchise = 'Brewers' WHERE franchise = 'Milwaukee Brewers';
UPDATE player SET franchise = 'Pirates' WHERE franchise = 'Pittsburgh Pirates';
UPDATE player SET franchise = 'Cardinals' WHERE franchise IN ('St Louis Cardinals', 'St. Louis Cardinals');
-- National League East
UPDATE player SET franchise = 'Braves' WHERE franchise = 'Atlanta Braves';
UPDATE player SET franchise = 'Marlins' WHERE franchise = 'Miami Marlins';
UPDATE player SET franchise = 'Mets' WHERE franchise = 'New York Mets';
UPDATE player SET franchise = 'Phillies' WHERE franchise = 'Philadelphia Phillies';
UPDATE player SET franchise = 'Nationals' WHERE franchise = 'Washington Nationals';
-- American League West
UPDATE player SET franchise = 'Astros' WHERE franchise = 'Houston Astros';
UPDATE player SET franchise = 'Angels' WHERE franchise = 'Los Angeles Angels';
UPDATE player SET franchise = 'Athletics' WHERE franchise = 'Oakland Athletics';
UPDATE player SET franchise = 'Mariners' WHERE franchise = 'Seattle Mariners';
UPDATE player SET franchise = 'Rangers' WHERE franchise = 'Texas Rangers';
-- American League Central
UPDATE player SET franchise = 'White Sox' WHERE franchise = 'Chicago White Sox';
UPDATE player SET franchise = 'Guardians' WHERE franchise = 'Cleveland Guardians';
UPDATE player SET franchise = 'Tigers' WHERE franchise = 'Detroit Tigers';
UPDATE player SET franchise = 'Royals' WHERE franchise = 'Kansas City Royals';
UPDATE player SET franchise = 'Twins' WHERE franchise = 'Minnesota Twins';
-- American League East
UPDATE player SET franchise = 'Orioles' WHERE franchise = 'Baltimore Orioles';
UPDATE player SET franchise = 'Red Sox' WHERE franchise = 'Boston Red Sox';
UPDATE player SET franchise = 'Yankees' WHERE franchise = 'New York Yankees';
UPDATE player SET franchise = 'Rays' WHERE franchise = 'Tampa Bay Rays';
UPDATE player SET franchise = 'Blue Jays' WHERE franchise = 'Toronto Blue Jays';
-- ============================================
-- VERIFICATION QUERY
-- ============================================
-- Run after migration to verify all 30 teams have correct values:
-- SELECT DISTINCT franchise FROM player ORDER BY franchise;
--
-- Expected output (30 city-agnostic franchise names):
-- Angels, Athletics, Blue Jays, Braves, Brewers, Cardinals, Cubs,
-- Diamondbacks, Dodgers, Giants, Guardians, Mariners, Marlins, Mets,
-- Nationals, Orioles, Padres, Phillies, Pirates, Rangers, Rays,
-- Red Sox, Reds, Rockies, Royals, Tigers, Twins, White Sox, Yankees
-- ============================================
-- ROLLBACK MIGRATION (if needed)
-- ============================================
-- Use these statements to revert to original values:
--
-- UPDATE player SET franchise = 'Arizona Diamondbacks' WHERE franchise = 'Diamondbacks' AND mlbclub LIKE '%Arizona%';
-- UPDATE player SET franchise = 'Atlanta Braves' WHERE franchise = 'Braves' AND mlbclub LIKE '%Atlanta%';
-- UPDATE player SET franchise = 'Baltimore Orioles' WHERE franchise = 'Orioles' AND mlbclub LIKE '%Baltimore%';
-- UPDATE player SET franchise = 'Boston Red Sox' WHERE franchise = 'Red Sox' AND mlbclub LIKE '%Boston%';
-- UPDATE player SET franchise = 'Chicago Cubs' WHERE franchise = 'Cubs' AND mlbclub LIKE '%Chicago%';
-- UPDATE player SET franchise = 'Chicago White Sox' WHERE franchise = 'White Sox' AND mlbclub LIKE '%Chicago%';
-- UPDATE player SET franchise = 'Cincinnati Reds' WHERE franchise = 'Reds' AND mlbclub LIKE '%Cincinnati%';
-- UPDATE player SET franchise = 'Cleveland Guardians' WHERE franchise = 'Guardians' AND mlbclub LIKE '%Cleveland%';
-- UPDATE player SET franchise = 'Colorado Rockies' WHERE franchise = 'Rockies' AND mlbclub LIKE '%Colorado%';
-- UPDATE player SET franchise = 'Detroit Tigers' WHERE franchise = 'Tigers' AND mlbclub LIKE '%Detroit%';
-- UPDATE player SET franchise = 'Houston Astros' WHERE franchise = 'Astros' AND mlbclub LIKE '%Houston%';
-- UPDATE player SET franchise = 'Kansas City Royals' WHERE franchise = 'Royals' AND mlbclub LIKE '%Kansas%';
-- UPDATE player SET franchise = 'Los Angeles Angels' WHERE franchise = 'Angels' AND mlbclub LIKE '%Los Angeles%' AND mlbclub NOT LIKE '%Dodgers%';
-- UPDATE player SET franchise = 'Los Angeles Dodgers' WHERE franchise = 'Dodgers' AND mlbclub LIKE '%Los Angeles%';
-- UPDATE player SET franchise = 'Miami Marlins' WHERE franchise = 'Marlins' AND mlbclub LIKE '%Miami%';
-- UPDATE player SET franchise = 'Milwaukee Brewers' WHERE franchise = 'Brewers' AND mlbclub LIKE '%Milwaukee%';
-- UPDATE player SET franchise = 'Minnesota Twins' WHERE franchise = 'Twins' AND mlbclub LIKE '%Minnesota%';
-- UPDATE player SET franchise = 'New York Mets' WHERE franchise = 'Mets' AND mlbclub LIKE '%New York%';
-- UPDATE player SET franchise = 'New York Yankees' WHERE franchise = 'Yankees' AND mlbclub LIKE '%New York%';
-- UPDATE player SET franchise = 'Oakland Athletics' WHERE franchise = 'Athletics' AND mlbclub LIKE '%Oakland%';
-- UPDATE player SET franchise = 'Philadelphia Phillies' WHERE franchise = 'Phillies' AND mlbclub LIKE '%Philadelphia%';
-- UPDATE player SET franchise = 'Pittsburgh Pirates' WHERE franchise = 'Pirates' AND mlbclub LIKE '%Pittsburgh%';
-- UPDATE player SET franchise = 'San Diego Padres' WHERE franchise = 'Padres' AND mlbclub LIKE '%San Diego%';
-- UPDATE player SET franchise = 'San Francisco Giants' WHERE franchise = 'Giants' AND mlbclub LIKE '%San Francisco%';
-- UPDATE player SET franchise = 'Seattle Mariners' WHERE franchise = 'Mariners' AND mlbclub LIKE '%Seattle%';
-- UPDATE player SET franchise = 'St Louis Cardinals' WHERE franchise = 'Cardinals' AND mlbclub LIKE '%St%Louis%';
-- UPDATE player SET franchise = 'Tampa Bay Rays' WHERE franchise = 'Rays' AND mlbclub LIKE '%Tampa%';
-- UPDATE player SET franchise = 'Texas Rangers' WHERE franchise = 'Rangers' AND mlbclub LIKE '%Texas%';
-- UPDATE player SET franchise = 'Toronto Blue Jays' WHERE franchise = 'Blue Jays' AND mlbclub LIKE '%Toronto%';
-- UPDATE player SET franchise = 'Washington Nationals' WHERE franchise = 'Nationals' AND mlbclub LIKE '%Washington%';

156
sheets.py
View File

@ -1,156 +0,0 @@
import logging
from db_engine import Player, Card, Team, Cardset
PD_SHEET_KEY = '1xqPOrJIjdUWfDSFNnUiecRgo8DDKFKk2Pf1iQ4pTREM'
def send_to_sheets(sheets, sheet_key: str, worksheet_title: str, data_list: list, data_range: str):
this_sheet = sheets.open_by_key(sheet_key)
this_ws = this_sheet.worksheet_by_title(worksheet_title)
this_ws.update_values(
crange=data_range,
values=data_list
)
return this_sheet
def update_all_players(sheets):
player_list = Player.select()
logging.debug(f'send to sheets player_list: {player_list}')
player_data = []
for x in player_list:
player_data.append(
[
x.player_id, x.p_name, x.cost, x.image,
x.image2, x.mlbclub, x.franchise,
x.cardset.name, x.rarity.name, x.pos_1, x.pos_2,
x.pos_3, x.pos_4, x.pos_5, x.pos_6,
x.pos_7, x.pos_8, x.headshot, x.vanity_card,
x.strat_code, x.bbref_id,
x.description, x.cardset.for_purchase, x.cardset.in_packs
]
)
return send_to_sheets(
sheets,
sheet_key=PD_SHEET_KEY,
worksheet_title='All Players',
data_list=player_data,
data_range='A2'
)
def send_ai_cards(sheets):
card_list = Card.select().join(Team).where(Card.team.is_ai)
logging.debug(f'send to sheets card_list: {card_list}')
card_data = []
for x in card_list:
card_data.append([
x.player.cardset.name, x.player.p_name, x.player.rarity.name, x.player.image, x.player.image2,
x.player.pos_1,
x.player.pos_2, x.player.pos_3, x.player.pos_4, x.player.pos_5, x.player.pos_6, x.player.pos_7,
x.player.pos_8, x.player.cost, x.player.mlbclub, x.player.franchise, x.player.set_num, x.player.bbref_id,
x.player_id, x.id, x.team.id
])
return send_to_sheets(
sheets,
sheet_key=PD_SHEET_KEY,
worksheet_title='AI Cards',
data_list=card_data,
data_range='A2'
)
def post_new_cards(sheets, starting_id: int):
card_list = Card.select().where(Card.id >= starting_id)
logging.debug(f'post_new_cards to sheets card_list: {card_list}')
card_data = []
count = starting_id
for x in card_list:
while count < x.id:
card_data.append(['', '', '', '', ''])
count += 1
card_data.append([
x.player.cardset.name, x.player.p_name, x.player.rarity.name, x.player.image, x.player.image2,
x.player.pos_1,
x.player.pos_2, x.player.pos_3, x.player.pos_4, x.player.pos_5, x.player.pos_6, x.player.pos_7,
x.player.pos_8, x.player.cost, x.player.mlbclub, x.player.franchise, x.player.set_num, x.player.bbref_id,
x.player_id, x.id, x.team.id
])
count += 1
return send_to_sheets(
sheets,
sheet_key=PD_SHEET_KEY,
worksheet_title='All Cards',
data_list=card_data,
data_range=f'A{starting_id + 1}'
)
def post_deletion(sheets, del_ids: list):
del_data = []
deletion_ids = [int(x) for x in del_ids]
deletion_ids.sort()
logging.info(f'sorted: {deletion_ids}')
x = deletion_ids[0]
while x <= deletion_ids[-1]:
if x in deletion_ids:
del_data.append(['TRUE'])
else:
del_data.append([''])
x += 1
return send_to_sheets(
sheets,
sheet_key=PD_SHEET_KEY,
worksheet_title='All Cards',
data_list=del_data,
data_range=f'V{deletion_ids[0] + 1}'
)
# def update_one_player(sheets, this_player):
# logging.debug(f'send to sheets this_player: {this_player}')
# player_data = [[
# this_player['player_id'], this_player['p_name'], this_player['cost'], this_player['image'],
# this_player['image2'], this_player['mlbclub'], this_player['franchise'],
# this_player['cardset']['name'], this_player['rarity']['name'], this_player['pos_1'], this_player['pos_2'],
# this_player['pos_3'], this_player['pos_4'], this_player['pos_5'], this_player['pos_6'],
# this_player['pos_7'], this_player['pos_8'], this_player['headshot'], this_player['vanity_card'],
# this_player['strat_code'], this_player['bbref_id'],
# this_player['description'], this_player['cardset']['for_purchase'], this_player['cardset']['in_packs']
# ]]
#
# return send_to_sheets(
# sheets,
# sheet_key=PD_SHEET_KEY,
# worksheet_title='All Cards',
# data_list=player_data,
# data_range=f'A{this_player["player_id"] + 1}'
# )
# def update_many_players(sheets, player_list):
# logging.debug(f'send to sheets player_list: {player_list}')
# player_data = []
# for x in player_list:
# player_data.append(
# [
# x['player_id'], x['p_name'], x['cost'], x['image'],
# x['image2'], x['mlbclub'], x['franchise'],
# x['cardset']['name'], x['rarity']['name'], x['pos_1'], x['pos_2'],
# x['pos_3'], x['pos_4'], x['pos_5'], x['pos_6'],
# x['pos_7'], x['pos_8'], x['headshot'], x['vanity_card'],
# x['strat_code'], x['bbref_id'],
# x['description'], x['cardset']['for_purchase'], x['cardset']['in_packs']
# ]
# )
#
#