diff --git a/app/Dockerfile b/app/Dockerfile
index ddac9ee..3d8dbca 100644
--- a/app/Dockerfile
+++ b/app/Dockerfile
@@ -8,8 +8,6 @@ COPY . .
# build
RUN npx prisma generate
RUN npm run build
-# remove dev dependencies
-RUN npm prune --production
FROM node:alpine
@@ -23,6 +21,7 @@ COPY --from=build /app/.next ./.next
COPY --from=build /app/public ./public
COPY --from=build /app/tools ./tools
COPY --from=build /app/data ./data
+COPY --from=build /app/prisma ./prisma
EXPOSE 3000
CMD ["npm","run","start"]
diff --git a/app/app/account/signin/page.tsx b/app/app/account/signin/page.tsx
index b4eba82..c9b4f45 100644
--- a/app/app/account/signin/page.tsx
+++ b/app/app/account/signin/page.tsx
@@ -52,7 +52,7 @@ export default function Signin() {
Connectez vous
-
+
diff --git a/app/tools/createUser.mjs b/app/tools/createUser.mjs
new file mode 100644
index 0000000..061b56d
--- /dev/null
+++ b/app/tools/createUser.mjs
@@ -0,0 +1,51 @@
+import { PrismaClient } from '@prisma/client'
+import { createHmac } from "crypto"
+import 'dotenv/config'
+
+const secret = process.env.PASSWORD_SECRET ? process.env.PASSWORD_SECRET : ""
+
+const db = new PrismaClient()
+
+const users = [
+ "zuma",
+ "nicolo",
+ "gororeznor",
+ "ragdub",
+ "onenleir",
+ "triskell",
+ "anubis",
+ "asmolith",
+ "izameh",
+ "lucie",
+ "kellaubz",
+ "bertrand",
+ "tibalt",
+ "jean",
+ "mercant",
+ "axel",
+ "aeddis",
+ "demo_a",
+ "demo_b",
+ "demo_c",
+ "demode",
+]
+
+async function createUser(username) {
+ const email = username + "@example.com"
+ const password = username + "123"
+ const hashed_password = createHmac('sha256',secret).update(password).digest('hex')
+ const admin = true
+
+ const user = await db.utilisateurice.create({
+ data: {
+ username,
+ password: hashed_password,
+ email,
+ admin,
+ }
+ })
+
+ console.log(user.username)
+}
+
+users.forEach(createUser)
diff --git a/app/tools/updateDatabase.mjs b/app/tools/updateDatabase.mjs
index 3d8c80c..3dc5526 100644
--- a/app/tools/updateDatabase.mjs
+++ b/app/tools/updateDatabase.mjs
@@ -1,15 +1,28 @@
import 'dotenv/config'
import 'https'
import fs from 'fs'
+import { Readable } from 'stream'
+import { finished } from 'stream/promises'
import pg from 'pg'
const { Client } = pg
+console.log("Fetching latest Scryfall Bulk Data URL...")
+const bulkDataApi = await fetch('https://api.scryfall.com/bulk-data')
+const bulkDataApiJson = await bulkDataApi.json()
+const bulkDataDownloadUrl = bulkDataApiJson.data.filter((obj) => obj.type == "unique_artwork")[0].download_uri
+
+console.log("Downloading latest Scryfall Bulk Data...")
+const stream = fs.createWriteStream(import.meta.dirname + '/data/scryfall_data.json');
+const { body } = await fetch(bulkDataDownloadUrl);
+await finished(Readable.fromWeb(body).pipe(stream));
+
+console.log("Fetching latest sets list from Scryfall...")
const scryfallSets = await fetch('https://api.scryfall.com/sets');
console.log('Status Code:', scryfallSets.status);
-
const sets = await scryfallSets.json();
// Read the data from the exported fr_cards.json extracted from Scryfall Bulk Data
+console.log("Reading Bulk Data...")
const fileBytes = fs.readFileSync(import.meta.dirname + '/data/scryfall_data.json')
let scryfallData = JSON.parse(fileBytes)
@@ -25,6 +38,7 @@ await client.connect()
const two_faced_layouts = ["transform","modal_dfc","double_faced_token","reversible_card"]
+console.log("Starting updating database...")
try {
const setRes = await client.query('SELECT id FROM set')
const preUpdateSetRows = setRes.rows
@@ -35,7 +49,7 @@ try {
for (const set of sets.data) {
if(!preUpdateSetIds.includes(set.id)){
- const addingSetQuery = await client.query('INSERT INTO set(id, name_en, sanitized_name, code, set_type, released_at, icon_svg_uri) VALUES($1, $2, $3, $4, $5, $6, $7)', [set.id, set.name, set.name.replace(/[^a-zA-Z0-9]/gim,"-").toLowerCase(), set.code, set.set_type, set.released_at, set.icon_svg_uri])
+ await client.query('INSERT INTO set(id, name_en, sanitized_name, code, set_type, released_at, icon_svg_uri) VALUES($1, $2, $3, $4, $5, $6, $7)', [set.id, set.name, set.name.replace(/[^a-zA-Z0-9]/gim,"-").toLowerCase(), set.code, set.set_type, set.released_at, set.icon_svg_uri])
}
}
@@ -51,60 +65,77 @@ try {
// Define counter for logging
let total_inserted = 0
let total_skipped = 0
+ let total_updated = 0
+
+ const total_cards = scryfallData.length
// For each card check if we need to upload it to the database
for (const carte of scryfallData) {
- if(!preUpdateCardsIds.includes(carte.id) && carte.legalities.commander != "not_legal"){
- let type = ""
- const layout = carte.layout
- const card_type = (carte.type_line == undefined) ? carte.card_faces[0].type_line.toLowerCase() : carte.type_line.toLowerCase()
-
- let promo = (carte.promo_types == undefined) ? false : true
- let can_be_commander = (card_type.includes("legendary") && (card_type.includes("creature") || card_type.includes("planeswalker"))) ? true : false
-
-
-
- if(card_type.includes("creature")){
- type = "creature"
- } else if (card_type.includes("planeswalker")) {
- type = "planeswalker"
- } else if (card_type.includes("artifact")) {
- type = "artifact"
- } else if (card_type.includes("instant")) {
- type = "instant"
- } else if (card_type.includes("enchantment")) {
- type = "enchantment"
- } else if (card_type.includes("sorcery")) {
- type = "sorcery"
- } else if (card_type.includes("land")) {
- type = "land"
- }
-
- try {
- if(two_faced_layouts.includes(layout)) {
- const addingCardsQuery = await client.query('INSERT INTO carte(id, name, released_at, small_image, small_image_back, normal_image, normal_image_back, type_line, color_identity, set_id, rarity, cardmarket_uri, price, type, sanitized_name, set_code, layout, is_promo, can_be_commander) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19)', [carte.id, carte.name, carte.released_at, carte.card_faces[0].image_uris.small, carte.card_faces[1].image_uris.small, carte.card_faces[0].image_uris.normal, carte.card_faces[0].image_uris.normal, carte.type_line, carte.color_identity, carte.set_id, carte.rarity, carte.purchase_uris?.cardmarket, carte.prices.eur, type, carte.name.replace(/[^a-zA-Z0-9]/gim,"-").toLowerCase(), carte.set, layout, promo, can_be_commander])
-
- } else {
- const addingCardsQuery = await client.query('INSERT INTO carte(id, name, released_at, small_image, normal_image, type_line, color_identity, set_id, rarity, cardmarket_uri, price, type, sanitized_name, set_code, layout, is_promo, can_be_commander) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)', [carte.id, carte.name, carte.released_at, carte.image_uris.small, carte.image_uris.normal, carte.type_line, carte.color_identity, carte.set_id, carte.rarity, carte.purchase_uris?.cardmarket, carte.prices.eur, type, carte.name.replace(/[^a-zA-Z0-9]/gim,"-").toLowerCase(), carte.set, layout, promo, can_be_commander])
-
- }
- total_inserted = total_inserted + 1
- } catch (err) {
- console.log(carte.uri)
- console.log(carte.layout)
- console.log(err)
- total_skipped = total_skipped + 1
- }
-
- // Add the card to the database
- } else {
- total_skipped = total_skipped + 1
-
+ const total_processed = total_skipped + total_updated + total_inserted
+ if ((total_processed) % 1000 == 0) {
+ console.log(total_processed + "/" + total_cards)
}
+ if(carte.legalities.commander != "not_legal") {
+ if(!preUpdateCardsIds.includes(carte.id)){
+ let type = ""
+ const layout = carte.layout
+ const card_type = (carte.type_line == undefined) ? carte.card_faces[0].type_line.toLowerCase() : carte.type_line.toLowerCase()
+
+ let promo = (carte.promo_types == undefined) ? false : true
+ let can_be_commander = (card_type.includes("legendary") && (card_type.includes("creature") || card_type.includes("planeswalker"))) ? true : false
+
+
+
+ if(card_type.includes("creature")){
+ type = "creature"
+ } else if (card_type.includes("planeswalker")) {
+ type = "planeswalker"
+ } else if (card_type.includes("artifact")) {
+ type = "artifact"
+ } else if (card_type.includes("instant")) {
+ type = "instant"
+ } else if (card_type.includes("enchantment")) {
+ type = "enchantment"
+ } else if (card_type.includes("sorcery")) {
+ type = "sorcery"
+ } else if (card_type.includes("land")) {
+ type = "land"
+ }
+
+ try {
+ if(two_faced_layouts.includes(layout)) {
+ const addingCardsQuery = await client.query('INSERT INTO carte(id, name, released_at, small_image, small_image_back, normal_image, normal_image_back, type_line, color_identity, set_id, rarity, cardmarket_uri, price, type, sanitized_name, set_code, layout, is_promo, can_be_commander) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19)', [carte.id, carte.name, carte.released_at, carte.card_faces[0].image_uris.small, carte.card_faces[1].image_uris.small, carte.card_faces[0].image_uris.normal, carte.card_faces[0].image_uris.normal, carte.type_line, carte.color_identity, carte.set_id, carte.rarity, carte.purchase_uris?.cardmarket, carte.prices.eur, type, carte.name.replace(/[^a-zA-Z0-9]/gim,"-").toLowerCase(), carte.set, layout, promo, can_be_commander])
+
+ } else {
+ const addingCardsQuery = await client.query('INSERT INTO carte(id, name, released_at, small_image, normal_image, type_line, color_identity, set_id, rarity, cardmarket_uri, price, type, sanitized_name, set_code, layout, is_promo, can_be_commander) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)', [carte.id, carte.name, carte.released_at, carte.image_uris.small, carte.image_uris.normal, carte.type_line, carte.color_identity, carte.set_id, carte.rarity, carte.purchase_uris?.cardmarket, carte.prices.eur, type, carte.name.replace(/[^a-zA-Z0-9]/gim,"-").toLowerCase(), carte.set, layout, promo, can_be_commander])
+
+ }
+ total_inserted = total_inserted + 1
+ } catch (err) {
+ console.log(carte.uri)
+ console.log(carte.layout)
+ console.log(err)
+ total_skipped = total_skipped + 1
+ }
+ } else {
+ const query = 'UPDATE "carte" SET "price" = $1 WHERE "id" = $2'
+ try {
+ const updateQuery = await client.query(query, [carte.prices.eur, carte.id])
+ total_updated = total_updated + 1
+ } catch (err) {
+ total_skipped = total_skipped + 1
+ console.log(err)
+ console.log(query)
+ }
+ }
+ } else {
+ total_skipped = total_skipped + 1
+ }
}
console.log("Un total de " + total_inserted + " cartes ont été insérées.")
console.log("Un total de " + total_skipped + " cartes ont été ignorées.")
+ console.log("Un total de " + total_updated + " cartes ont été mises à jour.")
} catch (err) {
console.error(err);
} finally {