Skip to content

Commit

Permalink
Merge pull request #108 from poketrax/#104-Add-Pricing-data-from-poke…
Browse files Browse the repository at this point in the history
…data

#104 add pricing data from pokedata
  • Loading branch information
jgunzelman88 authored Feb 4, 2023
2 parents 3d62a7d + 5d4ab7d commit 90267c2
Show file tree
Hide file tree
Showing 42 changed files with 377 additions and 104 deletions.
21 changes: 19 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,25 @@ jobs:
TAURI_PRIVATE_KEY: ${{ secrets.SIGNING_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
with:
tagName: v__VERSION__ # tauri-action replaces \_\_VERSION\_\_ with the app version
tagName: v__VERSION__
releaseName: 'v__VERSION__'
releaseBody: 'See the assets to download this version and install.'
releaseDraft: true
prerelease: false
prerelease: false
update:
runs-on: ubuntu-latest
needs: [release]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- name: Create update.json
run: |
cd src-web
npm install
npm run build-update-file
- name: Add update.json to Release
uses: softprops/action-gh-release@v1
with:
files: |
update.json
token: "${{ secrets.SERVICE_ACCOUNT_TOKEN }}"
3 changes: 2 additions & 1 deletion src-pages/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"dev": "vite",
"build": "vite build --base=./",
"build-test": "vite build --base=/poketrax-pages/",
"build-prod": "vite build --base=/PokeTrax/ && node updater.js",
"build-prod": "vite build --base=/PokeTrax/",
"build-update-file": " node updater.js",
"preview": "vite preview",
"check": "svelte-check --tsconfig ./tsconfig.json"
},
Expand Down
2 changes: 1 addition & 1 deletion src-pages/updater.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as fs from "fs";
import fetch from "node-fetch";

let updateFile = "../docs/update.json";
let updateFile = "../update.json";
let tauriFile = fs.readFileSync("../src-tauri/tauri.conf.json");
let tauri = JSON.parse(tauriFile);
let version = tauri.package.version;
Expand Down
3 changes: 3 additions & 0 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use routes::img_handler;
use routes::admin;
use routes::poke_product;
use routes::collections;
use routes::prices;

mod models;
mod utils;
Expand Down Expand Up @@ -98,6 +99,8 @@ async fn start_rest_api() -> std::io::Result<()> {
.service(admin::admin_series_by_name)
.service(admin::admin_upsert_series)
.service(admin::admin_delete_series)

.service(prices::card_prices_ebay)

})
.bind(("127.0.0.1", PORT))?
Expand Down
11 changes: 0 additions & 11 deletions src-tauri/src/models/pokemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,4 @@ pub struct SealedProduct {
pub collection: Option<String>,
pub paid: Option<f64>,
pub count: Option<i64>,
}

pub struct SealedPrice {
pub name: String,
pub date: String,
pub vendor: String,
pub price: f64,
}
pub struct ProductList {
pub total: i64,
pub products: Vec<SealedProduct>,
}
2 changes: 1 addition & 1 deletion src-tauri/src/routes/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ pub async fn admin_upsert_card(card: web::Json<Card>) -> Result<impl Responder>
/// Delete Card
#[delete("/admin/pokemon/card")]
pub async fn admin_delete_card(card: web::Json<Card>) -> Result<impl Responder> {
match delete_card(card.0.name) {
match delete_card(&card.0.name) {
Ok(_) => Ok(HttpResponse::Accepted()),
Err(e) => Err(error::ErrorBadRequest(e)),
}
Expand Down
4 changes: 2 additions & 2 deletions src-tauri/src/routes/img_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ async fn card_img(req: HttpRequest) -> Result<impl Responder> {
.body(image_content))
} else {
//Try to pull card and cache it
match pokemon_data::get_card(id.to_string(), None) {
match pokemon_data::get_card(&id, None) {
Ok(card) => {
match shared::download_file(card.img.as_str(), path_name.as_str()).await {
Ok(()) => {
Expand All @@ -59,7 +59,7 @@ async fn card_img(req: HttpRequest) -> Result<impl Responder> {
}
}
}
Err(e) => {
Err(_) => {
log::warn!("Failed to find card : {}", id);
let image_content = web::block(|| std::fs::read(DEFAULT_IMG.as_str())).await??;
Ok(HttpResponse::build(StatusCode::OK)
Expand Down
3 changes: 2 additions & 1 deletion src-tauri/src/routes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ pub mod poke_product;
pub mod collections;
pub mod meta;
pub mod img_handler;
pub mod admin;
pub mod admin;
pub mod prices;
3 changes: 1 addition & 2 deletions src-tauri/src/routes/poke_card.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ pub async fn card_search_helper(
Ok(val) => count = val,
Err(e) => return Err(e),
}

let _cards: Vec<Card>;
let search = card_search_sql(
page,
Expand Down Expand Up @@ -284,7 +283,7 @@ pub async fn card_prices(
_: web::Query<PriceSearch>,
) -> Result<impl Responder> {
let _id = urlencoding::decode(id.as_str()).unwrap().to_string();
match get_card(_id, None) {
match get_card(&_id, None) {
Ok(card) => {
let mut prices: Vec<Price> = Vec::new();
let data_url = format!(
Expand Down
4 changes: 2 additions & 2 deletions src-tauri/src/routes/poke_product.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ pub async fn product_search(

let count: i64;

match pokemon_data::product_count(Some(name_filter.clone()), None).await {
match pokemon_data::product_count(Some(name_filter.clone()), None) {
Ok(val) => count = val,
Err(e) => return Err(error::ErrorInternalServerError(e)),
}

let products: Vec<SealedProduct>;
match pokemon_data::product_search_sql(*page, Some(name_filter.clone()), Some(sort), None).await
match pokemon_data::product_search_sql(*page, Some(name_filter.clone()), Some(sort), None)
{
Ok(val) => products = val,
Err(e) => return Err(error::ErrorInternalServerError(e)),
Expand Down
33 changes: 33 additions & 0 deletions src-tauri/src/routes/prices.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use serde::{Serialize, Deserialize};
use actix_web::{get, web, Responder, Result};
use urlencoding;
use crate::utils::prices_data::get_prices;

#[allow(non_snake_case)]
#[derive(Serialize)]
#[derive(Deserialize)]
pub struct Price {
pub date: String,
pub cardId: String,
pub variant: String,
pub rawPrice: f64,
pub gradedPriceTen: f64,
pub gradedPriceNine: f64,
}

#[derive(Serialize)]
#[derive(Deserialize)]
pub struct PriceSearch {
pub start: String
}

#[get("/pokemon/card/price/ebay/{id}")]
pub async fn card_prices_ebay(
id: web::Path<String>,
search_params: web::Query<PriceSearch>,
) -> Result<impl Responder> {
let _id = urlencoding::decode(&id).unwrap();
let start = urlencoding::decode(&search_params.start).unwrap();
let prices = get_prices(&_id, &start)?;
Ok(web::Json(prices))
}
31 changes: 15 additions & 16 deletions src-tauri/src/utils/pokemon_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ pub fn get_expansion(
FROM expansions
WHERE name = :name",
);
println!("Exp Name {}", _name);
let mut query = connection.prepare(&statement)?;
let rows = query.query_map(&[(":name", &_name)],
|row| {
Expand Down Expand Up @@ -505,9 +504,9 @@ mod card_search_tests {
/// # Arguments
/// * 'name_filter' - search term for the name of the card
/// * 'db_path' - path to sqlite database defaults to POKE_DB_PATH
pub fn get_card(name_filter: String, db_path: Option<String>) -> Result<Card, Box<dyn std::error::Error>> {
pub fn get_card(name_filter: &str, db_path: Option<String>) -> Result<Card, Box<dyn std::error::Error>> {
let cards;
match card_search_sql(0, Some(name_filter.clone()), None, None, None, db_path) {
match card_search_sql(0, Some(String::from(name_filter)), None, None, None, db_path) {
Ok(val) => cards = val,
Err(e) => return Err(Box::from(e)),
}
Expand Down Expand Up @@ -601,7 +600,7 @@ pub fn upsert_card(card: &Card) -> Result<(), Box<dyn std::error::Error>> {
/// Delete Card from admin database
/// #Argmuents
/// * cardId - card id of card to delete
pub fn delete_card(cardId: String) -> Result<(), Box<dyn std::error::Error>> {
pub fn delete_card(cardId: &str) -> Result<(), Box<dyn std::error::Error>> {
let connection = Connection::open(get_admin_file_path())?;
let mut statement = connection.prepare("DELETE FROM cards WHERE cardId = :cardId")?;
statement.execute(named_params!{":cardId": cardId})?;
Expand Down Expand Up @@ -641,7 +640,7 @@ mod upsert_card_test {
Ok(_) => assert!(true),
Err(e) => assert!(false, "Upsert error {}",e)
}
let result = get_card(card.name.clone(), Some(get_admin_file_path())).unwrap();
let result = get_card(&card.name, Some(get_admin_file_path())).unwrap();
assert!(result.cardId.eq(&card.cardId));
card.pokedex = 20000;
//update
Expand All @@ -650,10 +649,10 @@ mod upsert_card_test {
Ok(_) => assert!(true),
Err(e) => assert!(false, "Upsert error {}",e)
}
let result = get_card(card.name, Some(get_admin_file_path())).unwrap();
let result = get_card(&card.name, Some(get_admin_file_path())).unwrap();
assert!(result.pokedex == card.pokedex);
//delete
delete_card(card.cardId).unwrap();
delete_card(&card.cardId).unwrap();
}
}

Expand All @@ -665,7 +664,7 @@ mod upsert_card_test {
/// # Arguments
/// * 'name_filter' - search term for the name of the card
/// * 'db_path' - path to sqlite database defaults to POKE_DB_PATH
pub async fn product_count(name_filter: Option<String>, db_path: Option<String>) -> Result<i64, Box<dyn std::error::Error>> {
pub fn product_count(name_filter: Option<String>, db_path: Option<String>) -> Result<i64, Box<dyn std::error::Error>> {
let connection: Connection;
if db_path.is_none() {
connection = Connection::open(POKE_DB_PATH.as_str())?;
Expand Down Expand Up @@ -693,7 +692,7 @@ mod product_count_tests {
#[actix_web::test]
async fn product_count_test() {
let name_filter = Some(String::from("Charizard"));
let count = product_count(name_filter, None).await;
let count = product_count(name_filter, None);
match count {
Ok(val) => {
assert!(val > 10)
Expand All @@ -711,7 +710,7 @@ mod product_count_tests {
/// * 'name_filter' - search term for the name of the card
/// * 'sort' - ORDER BY statement for sorting results
/// * 'db_path' - path to sqlite database defaults to POKE_DB_PATH
pub async fn product_search_sql(
pub fn product_search_sql(
page: u32,
name_filter: Option<String>,
sort: Option<String>,
Expand Down Expand Up @@ -769,9 +768,9 @@ pub async fn product_search_sql(
mod product_tests {
use super::*;
use serde_json::to_string_pretty;
#[actix_web::test]
async fn get_product_count() {
let count = product_count(None, None).await;
#[test]
fn get_product_count() {
let count = product_count(None, None);
match count {
Ok(val) => {
assert!(val > 0)
Expand All @@ -782,9 +781,9 @@ mod product_tests {
}
}

#[actix_web::test]
async fn get_products() {
let products = product_search_sql(0, None, None, None).await;
#[test]
fn get_products() {
let products = product_search_sql(0, None, None, None);
match products {
Ok(val) => {
let msg = to_string_pretty(&val).unwrap();
Expand Down
56 changes: 55 additions & 1 deletion src-tauri/src/utils/prices_data.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,60 @@
use crate::routes::prices::Price;
use crate::utils::shared::get_data_dir;
use lazy_static::lazy_static;
use crate::utils::shared::{get_data_dir};
use rusqlite::{named_params, Connection, Result};

lazy_static! {
pub static ref PRICES_DB_PATH: String = format!("{}{}", get_data_dir(), "/prices.sql");
}
/// # Get Prices
/// * Get prices for a card given a start date. will pull prices from start to now.
/// # Arguments
/// * card_id - id of the card you want prices from.
/// * start - inclusive start data filter.
pub fn get_prices(card_id: &str, start: &str) -> Result<Vec<Price>, Box<dyn std::error::Error>> {
let connection = Connection::open(PRICES_DB_PATH.as_str())?;
let mut statement = connection.prepare(
"SELECT date, cardId, variant, rawPrice, gradedPriceTen, gradedPriceNine
FROM prices
WHERE cardId = :card_id
AND date(date) >= date(:date)
ORDER BY date(date) DESC",
)?;
let mut prices: Vec<Price> = Vec::new();
let _prices = statement.query_map(
named_params! {":card_id": &card_id, ":date": &start},
|row| {
let price = Price {
date: row.get(0).unwrap(),
cardId: row.get(1).unwrap(),
variant: row.get(2).unwrap_or_default(),
rawPrice: row.get(3).unwrap(),
gradedPriceTen: row.get(4).unwrap(),
gradedPriceNine: row.get(5).unwrap(),
};
Ok(price)
},
)?;
for price in _prices {
prices.push(price?)
}
Ok(prices)
}
#[cfg(test)]
mod price_tests {
use super::{*, get_prices};
use serde_json::to_string_pretty;
#[test]
fn get_prices_test() {
let result = get_prices("SWSH03-Darkness-Ablaze-Swanna-149", "2020-01-01");
match result {
Ok(val) => {
println!("prices {}", to_string_pretty(&val[0]).unwrap());
assert!(val.len() > 0)
}
Err(_) => {
assert!(false)
}
}
}
}
Loading

0 comments on commit 90267c2

Please sign in to comment.