diff --git a/Models/index.js b/Models/index.js index 0d1eb8d..5741bab 100644 --- a/Models/index.js +++ b/Models/index.js @@ -29,10 +29,10 @@ var pokeDexSchema = new mongoose.Schema({ var imagesSchema = new mongoose.Schema({ idNumber: Number, - "96x96Type": Object, - "96x96Base64": String, - "475x475Type:": Object, - "475x475Base64": String + iconType: Object, + iconBase64: String, + fullType: Object, + fullBase64: String }); var images = mongoose.model("images", imagesSchema); diff --git a/README.md b/README.md index a2182df..fd68e7f 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,8 @@ Reference "Script Definitions" section were needed. - [ Integration DataTables](https://www.youtube.com/watch?v=ZCKj0SJRTB8) ## Other Reading ## +### Node Specific ### +- [Base64 encoding with buffer](https://bit.ly/2TKgqPS) ### Authentication & Authorization - [JWT with Node.js](https://medium.com/better-programming/authentication-and-authorization-using-jwt-with-node-js-4099b2e6ca1f) ### Create React App diff --git a/SeedData/index.js b/SeedData/index.js index 77ffe35..9cf3824 100644 --- a/SeedData/index.js +++ b/SeedData/index.js @@ -1,13 +1,20 @@ var setPokemonCandyDistance = require('./setPokemonCandyDistance').setPokemonCandyDistance; var setPokemonEvolutionDistance = require('./setPokemonEvolutionCosts').setPokemonEvolutionDistance; +var upsertIconImages = require('./setPokemonImages').upsertIconImages; +var upsertFullImages = require('./setPokemonImages').upsertFullImages; + var jsonSettings = require('../settings.json'); const mongoose = require('mongoose'); mongoose.connect(jsonSettings.connectionString, - {useNewUrlParser: true, useUnifiedTopology: true}); + {useNewUrlParser: true, useUnifiedTopology: true, useFindAndModify: false}); var db = mongoose.connection; var argv = require('yargs') .usage('') + .alias('sii', 'setImagesIcon') + .describe('sii', "inserts icon images for pokemon 96px x 96px") + .alias('sif', 'setImagesFull') + .describe('sif', "Insert full images for pokemon 475px x 475px") .alias('sd', 'setDistances') .describe('sd', 'Replaces or adds all pokemon to db') .alias('se', 'setEvolutionCost') @@ -16,6 +23,24 @@ var argv = require('yargs') .alias('h', 'help') .argv; +if(argv.setImagesIcon){ + (async()=>{ + + await upsertIconImages(db).then(()=>{ + process.exit(); + }); + })(); +} + +if(argv.setImagesFull){ + (async()=>{ + + await upsertFullImages(db).then(()=>{ + process.exit(); + }); + })(); +} + if(argv.setDistances) { (async()=>{ diff --git a/SeedData/setPokemonImages.js b/SeedData/setPokemonImages.js index 320637d..e6b5238 100644 --- a/SeedData/setPokemonImages.js +++ b/SeedData/setPokemonImages.js @@ -1,11 +1,14 @@ const fetch = require('node-fetch'); +const fileType = require('file-type'); +const imageModel = require('../Models/').images; +const idPadding = require('../src/setIdPadding').setIdNumberPadding; //loop through all pokemon in the pokedex collection async function getPokemon() { return new Promise((resolve, reject) => { - fetch('/pokemon') + fetch('http://localhost:3000/pokemon') .then(res => res.json()) .then(pokemon => { @@ -18,25 +21,74 @@ async function getPokemon() } //for each pokemon fetch image from https://assets.thesilphroad.com/img/pokemon/icons/96x96/10.png +async function upsertIconImages(db){ + const fetch96 = "https://assets.thesilphroad.com/img/pokemon/icons/96x96/"; + return new Promise((resolve,reject)=>{ + db.on('error', console.error.bind(console, 'connection error')); + db.once('open', async()=>{ + const pokemonList = await getPokemon(); + for(var a = 0; a <= pokemonList.length -1; a++){ + let idNumber = pokemonList[a].idNumber; + const response = await fetch(`${fetch96}${idNumber}.png`); + //return the buffer for each image + const buffer = await response.buffer(); + //return the type from the image + const type = await fileType.fromBuffer(buffer); + //convert the buffer to base64 + const base64String = Buffer.from(buffer).toString('base64'); + //console.log(base64String); - //return the buffer for each image + imageModel.findOneAndUpdate({idNumber: idNumber}, { + idNumber: idNumber, + iconType: type, + iconBase64: base64String + },{upsert: true}, (err, doc)=>{ + if(err) reject(err); - //convert the buffer to base64 - - //return the type from the image + console.log(`updated pokemon #${idNumber} 96x96 image`); + }); + + } + resolve(); + }); + }); + +} - //save file name to the images 96x96 collection as {id}.png +async function upsertFullImages(db){ + return new Promise((resolve,reject)=>{ + const fetch475 = 'https://db.pokemongohub.net/images/official/full/'; + db.on('error', console.error.bind(console, 'connection error')); + db.once('open', async()=>{ + const pokemonList = await getPokemon(); + for(var a = 0; a <= pokemonList.length -1; a++){ + let idNumber = idPadding(pokemonList[a].idNumber); + const response = await fetch(`${fetch475}${idNumber}.png`); + //return the buffer for each image + const buffer = await response.buffer(); + //return the type from the image + const type = await fileType.fromBuffer(buffer); + //convert the buffer to base64 + const base64String = Buffer.from(buffer).toString('base64'); -//for each pokemon fetch image from https://db.pokemongohub.net/images/official/full/10.png - //if the id is less than 100 use "0" + id - //if the id is less than 10 use "00"+id + imageModel.findOneAndUpdate({idNumber: idNumber}, { + idNumber: idNumber, + fullType: type, + fullBase64: base64String + },{upsert: true}, (err, doc)=>{ + if(err) reject(err); - //retun the buffer for each image - //convert the buffer to base64 - //retun the file type from the image - //save file name to db as {id.png} - //save base64 string to the 475x475 collection + console.log(`updated pokemon #${idNumber} 475x475 image`); + }); + + } + resolve(); + }); + }); +} module.exports = { - getPokemon + upsertIconImages, + upsertFullImages, + getPokemon } \ No newline at end of file diff --git a/package.json b/package.json index 751acd7..38533af 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "datatables.net-buttons": "^1.6.2", "datatables.net-responsive": "^2.2.5", "express": "^4.17.1", + "file-type": "^14.5.0", "jquery": "^3.5.1", "jsonwebtoken": "^8.5.1", "mongodb": "^3.5.7", diff --git a/server/index.js b/server/index.js index 6ae7cbf..0dc5b2a 100644 --- a/server/index.js +++ b/server/index.js @@ -84,10 +84,16 @@ app.get('/pokemon', async (req, res) => } }); +app.get('/pokemon/image/:id', async(req, res)=>{ + const images = mongoose.model('images'); + const singlePokeImage = await images.find({idNumber: req.params.id}).exec(); + return res.json(singlePokeImage[0]); +}); + app.get('/pokemon/:id', async (req, res) => { const singlePoke = await pokeDex.find({idNumber: req.params.id}).exec(); - res.json(singlePoke); + res.json(singlePoke[0]); }); app.post('/pokemon/reset/:id', async (req, res) => diff --git a/src/components/Pokemon.css b/src/components/Pokemon.css index 109a12b..4cc0f63 100644 --- a/src/components/Pokemon.css +++ b/src/components/Pokemon.css @@ -1,3 +1,5 @@ + +#single-pokemon .breadcrumb { margin-bottom: 0px; } .type-other{ background-color: #3c3c3c; } .type-bug{background-color: #A8B820;} .type-dark{background-color: #705848;} diff --git a/src/components/Pokemon.js b/src/components/Pokemon.js index bb25bf6..be08129 100644 --- a/src/components/Pokemon.js +++ b/src/components/Pokemon.js @@ -15,18 +15,19 @@ class Pokemon extends React.Component pokemon: {} } } - componentDidMount() + async componentDidMount() { - const id = this.props.match.params.id; - fetch(`/pokemon/${id}`).then(res => res.json()) - .then(pokemonA =>{ - fetch(`https://pokeapi.co/api/v2/pokemon/${id}`) - .then(res => res.json()) - .then(pokemonB => { - const pokemonType = pokemonB.types[pokemonB.types.length-1].type.name; - this.setState({pokemon: {...pokemonA[0], type: pokemonType}}); - }); - }); + const id = this.props.match.params.id; + var pokemon = await fetch(`/pokemon/${id}`).then(res => res.json()); + var types = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`).then(res=>res.json()); + pokemon.types = types.types; + var images = await fetch (`/pokemon/image/${id}`).then(res=>res.json()); + pokemon.images = images; + + this.setState({ + pokemon: pokemon + }); + } handleChange(event) { @@ -67,20 +68,16 @@ class Pokemon extends React.Component render() { - var idStr = this.state.pokemon.idNumber; - if (this.state.pokemon.idNumber < 10) - { - idStr = "00" + this.state.pokemon.idNumber; - } - else if (this.state.pokemon.idNumber < 100) - { - idStr = "0" + this.state.pokemon.idNumber; + var pokemonImgUrl = ""; + var type = ""; + + if(Object.keys(this.state.pokemon).length !== 0){ + pokemonImgUrl = `data:${this.state.pokemon.images.fullType.mime || ""};base64,${this.state.pokemon.images.fullBase64 || ""}`; + type= this.state.pokemon.types[this.state.pokemon.types.length -1].type.name; } - const pokemonImgUrl = "https://db.pokemongohub.net/images/official/full/" + idStr + ".png"; - - return ( -