Skip to content

Commit

Permalink
Python Script
Browse files Browse the repository at this point in the history
Aggiunto script python per la ricerca delle carte implementate nel
server API.
  • Loading branch information
ncvescera committed Feb 19, 2023
1 parent 1dfabfd commit d4abf4d
Show file tree
Hide file tree
Showing 5 changed files with 275 additions and 0 deletions.
48 changes: 48 additions & 0 deletions py-card_explorer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# py-card_explorer

Questo è uno script in python che permette di trovare tutte le carte di Magic implementate nell'API
a cui Java fa riferimento per ottenere i dati.

## Installazione

È consigliato utilizzare un ambiente come `venv` o `anaconda` per eseguire questo script.
Il file `create_env.sh` creerà in automatico un ambiente `venv`.

Una volta creato l'abimente ed attivato (per venv `source .venv/bin/activate`) utilizzare il seguente comando per installare i requirements
necessari:

`pip install -r requirements.txt`

o in alternativa:

`python3 -m pip install -r requirements.txt`

## Utilizzo

Una volta installati i requirements necessari, se non avete attivato l'abimente fatelo (per venv `source .venv/bin/actiate`)
e lanciate lo script con

`python3 mtg_card_explorer.py`

Sono implementate 4 funzioni differenti:

- `Trova le carte esistenti`: avvia la ricerca delle carte presenti nell'API.
Effettua una chiamata con ID progressivo, attende qualche secondo per evitare di venir bloccato
dal server e continua. È possibile specificare i seguenti parametri:
- `ID start`: id della carta da cui partire per la ricerca
- `ID end`: ultimo id della carta dopo il quale termina la ricerca
Se lasciati vuoti utilizzeranno l'ultimo id trovato durante la ricerca (verrà creato un file apposito dove saranno salvati i dati).
È possibile interrompere e riprendere la ricerca quando si vuole, lo script è abbastanza intelligente da non aggiungere doppioni.
Una volta terminata la ricerca verrà generato un file di nome `all_cards.json` dove saranno contenuti tutti i dati (sotto forma di josn)
delle carte trovate durante la ricerca.
- `Esplora le carte trovate`: una volta trovate tutte le carte con la fase
di ricerca apposita, questo stamperà a video una tebella con tutte le carte
trovate ed alcune loro proprietà di interesse.
- `Cerca nelle carte`: permette di cercare per parole chiavi all'interno di alcuni campi come:
- `type`
- `subtype`
- `name`
- `abilities`
- `Rimuovi tutti i file generati da questo script`: elimina tutti i file generati da questo script:
- `all_cards.json`
- `.lastindex`
1 change: 1 addition & 0 deletions py-card_explorer/create_env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
python3 -m venv .venv
222 changes: 222 additions & 0 deletions py-card_explorer/mtg_card_explorer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
import requests
import json
from time import sleep
from os.path import exists
import inquirer
from pprint import pprint
from os import remove

from rich.console import Console
from rich.table import Table
from rich.progress import track
from rich.progress import Progress
from rich.prompt import Prompt
from rich.live import Live
from rich.layout import Layout


# --- Global VARS
CARD_FILE = "all_cards.json"
LAST_INDEX_FILE = ".lastindex"

API_URL = "https://www.afterlifegdr.com/test/mtg/testjson.php"

CMDS_MAP = ['Trova le carte esistenti',
'Esplora le carte trovate',
'Rimuovi tutti i file generati da questo script',
'Cerca nelle carte',
]


# --- Output Formatted Consoles
console = Console()
success_console = Console(stderr=True, style="bold green")
info_console = Console(stderr=True, style="bold")
error_console = Console(stderr=True, style="bold red")


# --- Aux Functions
def get_card(card_id: int) -> dict:
response = requests.get(
API_URL,
params={'cardid': card_id},
timeout=3
)

if response.status_code != 200:
error_console.print("Errore nella chiamata API !")
return None

return response.json()


def generate_card_table(cards: list, print_table=True) -> Table:
table = Table(title="Carte Trovate", show_lines=True)

table.add_column("ID", style="cyan", no_wrap=True)
table.add_column("Nome", style="magenta")
table.add_column("Keyword Abilities", style="red")
table.add_column("Subtipes", style="green")
table.add_column("Text Abilities", style="white")

for card in cards:
table.add_row(
str(card['card']['cardID']),
card['card']['cardName'],
", ".join(card['face1']['keywordAbilities']),
", ".join(card['face1']['subtypes']),
" | ".join(card['face1']['abilities'])
)

if print_table:
console.print(table)
info_console.print(f"Totale Carte: {len(cards)}")

return table


def check_cards_file(print_message=True):
if not exists(CARD_FILE):
if print_message:
error_console.print("Devi prima trovare le carte !")

return False

return True


def open_cards_file(print_message=True):
if not exists(CARD_FILE):
if print_message:
error_console.print("Devi prima trovare le carte !")

return None

with open(CARD_FILE, "r") as conf:
if print_message:
info_console.print(" Riapro la lista di carte già trovate")

cards = json.loads(conf.read())

return cards


# --- Commands Functions
def query_all_cards(start=0, end=3000):
cards = []

if isinstance(end, str):
if end != '':
end = int(end)
else:
end = 3000

if isinstance(start, str):
if start != '':
start = int(start)
else:
start = 0

if exists(LAST_INDEX_FILE) and start == 0:
with open(LAST_INDEX_FILE, "r") as conf:
info_console.print(" Riprendo dall'ultimo id provato")
start = int(conf.read())

if exists(CARD_FILE):
with open(CARD_FILE, "r") as conf:
info_console.print(" Riapro la lista di carte già trovate")
cards = json.loads(conf.read())

max_range = range(start, end)
info_console.print(f" Inizio la ricerca degli ID (da {start} a {end})")

try:
with Progress(console=success_console) as progres:
task = progres.add_task(
"Trovo le carte ...", completed=start, total=end)
for id in max_range:
sleep(.5)
progres.advance(task)
progres.update(
task, description=f"Trovo le carte (ID: {id}) ...")

tmp = get_card(id)

if tmp is None:
continue

success_console.print(f" ++ Trovata Carta {id}")

if tmp in cards:
success_console.print(" [yellow]Carta esistente ![/yellow]")
continue

cards.append(tmp)

except KeyboardInterrupt:
info_console.print(" Interrotta ricerca ")
except Exception:
error_console.print(" Si è verificato qualche problema :(")
finally:
with open(LAST_INDEX_FILE, "w") as conf:
info_console.print(" Salvo l'ultimo id provato")
conf.write(f"{id}")

info_console.print(" Ricerca Terminata")

return cards


def browse_cards():
cards = open_cards_file()

if cards is None:
return

_ = generate_card_table(cards)


def search_card():
if not exists(CARD_FILE):
error_console.print("Devi prima trovare le carte !")
return

with open(CARD_FILE, "r") as conf:
info_console.print(" Riapro la lista di carte già trovate")
cards = json.loads(conf.read())

while True:
search_word = Prompt.ask("[[yellow bold]?[/yellow bold]] Cerca una parola", default="'q' per uscire")

if search_word == 'q':
break

filtered_cards = [card for card in cards if search_word in card['card']['cardName'] or search_word == str(card['card']['cardID']) or any(search_word in s.lower() for s in card['face1']['keywordAbilities']) or any(search_word in s.lower() for s in card['face1']['subtypes']) or any(search_word in s.lower() for s in card['face1']['types'])]

_ = generate_card_table(filtered_cards)


def main():
match inquirer.list_input("Comandi", choices=list(CMDS_MAP)):
case 'Trova le carte esistenti':
start = inquirer.text("ID Partenza (default l'ultimo usato)")
end = inquirer.text("ID Fine (default 3000)")
result = query_all_cards(start=start, end=end)

with open(CARD_FILE, "w") as f:
f.write(json.dumps(result))

case 'Esplora le carte trovate':
browse_cards()

case 'Cerca nelle carte':
search_card()

case 'Rimuovi tutti i file generati da questo script':
info_console.print(" Rimuovo tutti i file generati")
remove(CARD_FILE)
remove(LAST_INDEX_FILE)


if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions py-card_explorer/old_allcards.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions py-card_explorer/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
requests
inquirer
rich

0 comments on commit d4abf4d

Please sign in to comment.