Skip to content
Open

1.8.7 #235

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 .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ on:
- main

env:
VERSION_NUMBER: 'v1.8.6'
VERSION_NUMBER: 'v1.8.7'
DOCKERHUB_REGISTRY_NAME: 'digitalghostdev/poke-cli'
AWS_REGION: 'us-west-2'

Expand Down
2 changes: 1 addition & 1 deletion .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ builds:
- windows
- darwin
ldflags:
- -s -w -X main.version=v1.8.6
- -s -w -X main.version=v1.8.7

archives:
- formats: [ 'zip' ]
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ RUN go mod download

COPY . .

RUN go build -ldflags "-X main.version=v1.8.6" -o poke-cli .
RUN go build -ldflags "-X main.version=v1.8.7" -o poke-cli .

# build 2
FROM --platform=$BUILDPLATFORM alpine:3.23
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<img width="425" src="poke-cli.png" alt="pokemon-logo"/>
<h4></h4>
<img src="https://img.shields.io/github/v/release/digitalghost-dev/poke-cli?style=flat-square&logo=git&logoColor=FFCC00&label=Release%20Version&labelColor=EEE&color=FFCC00" alt="version-label">
<img src="https://img.shields.io/docker/image-size/digitalghostdev/poke-cli/v1.8.6?arch=arm64&style=flat-square&logo=docker&logoColor=FFCC00&labelColor=EEE&color=FFCC00" alt="docker-image-size">
<img src="https://img.shields.io/docker/image-size/digitalghostdev/poke-cli/v1.8.7?arch=arm64&style=flat-square&logo=docker&logoColor=FFCC00&labelColor=EEE&color=FFCC00" alt="docker-image-size">
<img src="https://img.shields.io/github/actions/workflow/status/digitalghost-dev/poke-cli/ci.yml?branch=main&style=flat-square&logo=github&logoColor=FFCC00&label=CI&labelColor=EEE&color=FFCC00" alt="ci-status-badge">
</div>
<div align="center">
Expand Down Expand Up @@ -96,11 +96,11 @@ Cloudsmith is a fully cloud-based service that lets you easily create, store, an
3. Choose how to interact with the container:
* Run a single command and exit:
```bash
docker run --rm -it digitalghostdev/poke-cli:v1.8.6 <command> [subcommand] [flag]
docker run --rm -it digitalghostdev/poke-cli:v1.8.7 <command> [subcommand] [flag]
```
* Enter the container and use its shell:
```bash
docker run --rm -it --name poke-cli --entrypoint /bin/sh digitalghostdev/poke-cli:v1.8.6 -c "cd /app && exec sh"
docker run --rm -it --name poke-cli --entrypoint /bin/sh digitalghostdev/poke-cli:v1.8.7 -c "cd /app && exec sh"
# placed into the /app directory, run the program with './poke-cli'
# example: ./poke-cli ability swift-swim
```
Expand Down
36 changes: 33 additions & 3 deletions card_data/pipelines/definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,26 @@
import dagster as dg

from .defs.extract.tcgcsv.extract_pricing import build_dataframe
from .defs.extract.tcgdex.extract_sets import extract_sets_data
from .defs.extract.tcgdex.extract_series import extract_series_data
from .defs.load.tcgcsv.load_pricing import load_pricing_data, data_quality_checks_on_pricing
from .defs.load.tcgdex.load_sets import load_sets_data, data_quality_check_on_sets
from .defs.load.tcgdex.load_series import load_series_data, data_quality_check_on_series
from .sensors import discord_success_sensor, discord_failure_sensor


@definitions
def defs() -> dg.Definitions:
# load_from_defs_folder discovers dbt assets from transform_data.py
folder_defs: dg.Definitions = load_from_defs_folder(project_root=Path(__file__).parent.parent)
return dg.Definitions.merge(folder_defs, defs_pricing)
return dg.Definitions.merge(folder_defs, defs_discord_sensors, defs_pricing, defs_sets, defs_series)

# Define the pricing pipeline job that materializes the assets and downstream dbt model

defs_discord_sensors: dg.Definitions = dg.Definitions(
sensors=[discord_success_sensor, discord_failure_sensor],
)

# Pricing pipeline
pricing_pipeline_job = dg.define_asset_job(
name="pricing_pipeline_job",
selection=dg.AssetSelection.assets(build_dataframe).downstream(include_self=True),
Expand All @@ -32,5 +41,26 @@ def defs() -> dg.Definitions:
assets=[build_dataframe, load_pricing_data, data_quality_checks_on_pricing],
jobs=[pricing_pipeline_job],
schedules=[price_schedule],
sensors=[discord_success_sensor, discord_failure_sensor]
)

# Series pipeline
series_pipeline_job = dg.define_asset_job(
name="series_pipeline_job",
selection=dg.AssetSelection.assets(extract_series_data).downstream(include_self=True),
)

defs_series: dg.Definitions = dg.Definitions(
assets=[extract_series_data, load_series_data, data_quality_check_on_series],
jobs=[series_pipeline_job],
)

# Sets pipeline
sets_pipeline_job = dg.define_asset_job(
name="sets_pipeline_job",
selection=dg.AssetSelection.assets(extract_sets_data).downstream(include_self=True),
)

defs_sets: dg.Definitions = dg.Definitions(
assets=[extract_sets_data, load_sets_data, data_quality_check_on_sets],
jobs=[sets_pipeline_job],
)
2 changes: 1 addition & 1 deletion card_data/pipelines/poke_cli_dbt/dbt_project.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: 'poke_cli_dbt'
version: '1.8.6'
version: '1.8.7'

profile: 'poke_cli_dbt'

Expand Down
4 changes: 4 additions & 0 deletions card_data/pipelines/sensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ def discord_success_sensor(context: RunStatusSensorContext):
timeout=10,
)
context.log.info(f"n8n response: {response.status_code}")
except requests.RequestException as e:
context.log.error(f"Requests or network error: {e}")
except Exception as e:
context.log.error(f"Failed to send notification: {e}")

Expand All @@ -36,5 +38,7 @@ def discord_failure_sensor(context: RunStatusSensorContext):
timeout=10,
)
context.log.info(f"n8n response: {response.status_code}")
except requests.RequestException as e:
context.log.error(f"Requests or network error: {e}")
except Exception as e:
context.log.error(f"Failed to send notification: {e}")
135 changes: 113 additions & 22 deletions cmd/card/cardlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import (
"fmt"
"io"
"net/http"
"strings"
"time"

"github.com/charmbracelet/bubbles/table"
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/digitalghost-dev/poke-cli/styling"
Expand All @@ -19,13 +21,42 @@ type CardsModel struct {
ImageMap map[string]string
PriceMap map[string]string
RegulationMarkMap map[string]string
AllRows []table.Row
Quitting bool
Search textinput.Model
SelectedOption string
SeriesName string
Table table.Model
TableStyles table.Styles
ViewImage bool
}

const (
activeTableSelectedBg lipgloss.Color = "#FFCC00"
inactiveTableSelectedBg lipgloss.Color = "#808080"
)

func cardTableStyles(selectedBg lipgloss.Color) table.Styles {
s := table.DefaultStyles()
s.Header = s.Header.
BorderStyle(lipgloss.NormalBorder()).
BorderForeground(lipgloss.Color("#FFCC00")).
BorderBottom(true)
s.Selected = s.Selected.
Foreground(lipgloss.Color("#000")).
Background(selectedBg)
return s
}

func (m *CardsModel) syncTableStylesForFocus() {
if m.Search.Focused() {
m.TableStyles = cardTableStyles(inactiveTableSelectedBg)
} else {
m.TableStyles = cardTableStyles(activeTableSelectedBg)
}
m.Table.SetStyles(m.TableStyles)
}

func (m CardsModel) Init() tea.Cmd {
return nil
}
Expand All @@ -36,16 +67,46 @@ func (m CardsModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "esc", "ctrl+c":
case "ctrl+c":
m.Quitting = true
return m, tea.Quit
case " ":
m.ViewImage = true
case "esc":
// If in the search bar, exit search mode instead of quitting.
if m.Search.Focused() {
m.Search.Blur()
m.Table.Focus()
m.syncTableStylesForFocus()
return m, nil
}
m.Quitting = true
return m, tea.Quit
case "?":
if !m.Search.Focused() {
m.ViewImage = true
return m, tea.Quit
}
case "tab":
if m.Search.Focused() {
m.Search.Blur()
m.Table.Focus()
} else {
m.Table.Blur()
m.Search.Focus()
}
m.syncTableStylesForFocus()
return m, nil
}
}

m.Table, bubbleCmd = m.Table.Update(msg)
if m.Search.Focused() {
prev := m.Search.Value()
m.Search, bubbleCmd = m.Search.Update(msg)
if m.Search.Value() != prev {
m.applyFilter()
}
} else {
m.Table, bubbleCmd = m.Table.Update(msg)
}

// Keep the selected option in sync on every update
if row := m.Table.SelectedRow(); len(row) > 0 {
Expand All @@ -58,6 +119,28 @@ func (m CardsModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, bubbleCmd
}

func (m *CardsModel) applyFilter() {
q := strings.TrimSpace(strings.ToLower(m.Search.Value()))
if q == "" {
m.Table.SetRows(m.AllRows)
m.Table.SetCursor(0)
return
}

filtered := make([]table.Row, 0, len(m.AllRows))
for _, r := range m.AllRows {
if len(r) == 0 {
continue
}
if strings.Contains(strings.ToLower(r[0]), q) {
filtered = append(filtered, r)
}
}

m.Table.SetRows(filtered)
m.Table.SetCursor(0)
}

func (m CardsModel) View() string {
if m.Quitting {
return "\n Quitting card search...\n\n"
Expand All @@ -75,7 +158,8 @@ func (m CardsModel) View() string {
selectedCard = cardName + "\n---\n" + price + "\n---\n" + illustrator + "\n---\n" + regulationMark
}

leftPanel := styling.TypesTableBorder.Render(m.Table.View())
leftContent := lipgloss.JoinVertical(lipgloss.Left, m.Search.View(), m.Table.View())
leftPanel := styling.TypesTableBorder.Render(leftContent)

rightPanel := lipgloss.NewStyle().
Width(40).
Expand All @@ -87,9 +171,10 @@ func (m CardsModel) View() string {

screen := lipgloss.JoinHorizontal(lipgloss.Top, leftPanel, rightPanel)

return fmt.Sprintf("Highlight a card!\n%s\n%s",
return fmt.Sprintf(
"Highlight a card!\n%s\n%s",
screen,
styling.KeyMenu.Render("↑ (move up)\n↓ (move down)\nspace (view image)\nctrl+c | esc (quit)"))
styling.KeyMenu.Render("↑ (move up)\n↓ (move down)\n? (view image)\ntab (toggle search)\nctrl+c | esc (quit)"))
}

type cardData struct {
Expand Down Expand Up @@ -117,10 +202,13 @@ func CardsList(setID string) (CardsModel, error) {

// Extract card names and build table rows + price map
rows := make([]table.Row, len(allCards))
allRows := rows

priceMap := make(map[string]string)
imageMap := make(map[string]string)
illustratorMap := make(map[string]string)
regulationMarkMap := make(map[string]string)

for i, card := range allCards {
rows[i] = []string{card.NumberPlusName}
if card.MarketPrice != 0 {
Expand All @@ -144,29 +232,32 @@ func CardsList(setID string) (CardsModel, error) {
imageMap[card.NumberPlusName] = card.ImageURL
}

ti := textinput.New()
ti.Placeholder = "type name..."
ti.Prompt = "🔎 "
ti.CharLimit = 24
ti.Width = 30
ti.Blur()

t := table.New(
table.WithColumns([]table.Column{{Title: "Card Name", Width: 35}}),
table.WithRows(rows),
table.WithFocused(true),
table.WithHeight(28),
table.WithHeight(27),
)

s := table.DefaultStyles()
s.Header = s.Header.
BorderStyle(lipgloss.NormalBorder()).
BorderForeground(lipgloss.Color("#FFCC00")).
BorderBottom(true)
s.Selected = s.Selected.
Foreground(lipgloss.Color("#000")).
Background(lipgloss.Color("#FFCC00"))
t.SetStyles(s)
styles := cardTableStyles(activeTableSelectedBg)
t.SetStyles(styles)

return CardsModel{
IllustratorMap: illustratorMap,
ImageMap: imageMap,
PriceMap: priceMap,
RegulationMarkMap: regulationMarkMap,
Table: t,
AllRows: allRows,
IllustratorMap: illustratorMap,
ImageMap: imageMap,
PriceMap: priceMap,
RegulationMarkMap: regulationMarkMap,
Search: ti,
Table: t,
TableStyles: styles,
}, nil
}

Expand Down
Loading