Merge pull request 'eecliptica' (#34) from eecliptica into master
Reviewed-on: #34
This commit is contained in:
		
						commit
						de46e9bf50
					
				
							
								
								
									
										36
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										36
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -9,6 +9,7 @@ | |||||||
|       "version": "1.0.1", |       "version": "1.0.1", | ||||||
|       "license": "MIT", |       "license": "MIT", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|  |         "axios": "^1.7.7", | ||||||
|         "bcrypt": "^5.1.0", |         "bcrypt": "^5.1.0", | ||||||
|         "body-parser": "^1.19.0", |         "body-parser": "^1.19.0", | ||||||
|         "cookie-parser": "^1.4.5", |         "cookie-parser": "^1.4.5", | ||||||
| @ -608,12 +609,14 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/axios": { |     "node_modules/axios": { | ||||||
|       "version": "0.27.2", |       "version": "1.7.7", | ||||||
|       "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", |       "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", | ||||||
|       "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", |       "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", | ||||||
|  |       "license": "MIT", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "follow-redirects": "^1.14.9", |         "follow-redirects": "^1.15.6", | ||||||
|         "form-data": "^4.0.0" |         "form-data": "^4.0.0", | ||||||
|  |         "proxy-from-env": "^1.1.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "node_modules/balanced-match": { |     "node_modules/balanced-match": { | ||||||
| @ -1985,15 +1988,16 @@ | |||||||
|       "dev": true |       "dev": true | ||||||
|     }, |     }, | ||||||
|     "node_modules/follow-redirects": { |     "node_modules/follow-redirects": { | ||||||
|       "version": "1.15.2", |       "version": "1.15.9", | ||||||
|       "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", |       "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", | ||||||
|       "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", |       "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", | ||||||
|       "funding": [ |       "funding": [ | ||||||
|         { |         { | ||||||
|           "type": "individual", |           "type": "individual", | ||||||
|           "url": "https://github.com/sponsors/RubenVerborgh" |           "url": "https://github.com/sponsors/RubenVerborgh" | ||||||
|         } |         } | ||||||
|       ], |       ], | ||||||
|  |       "license": "MIT", | ||||||
|       "engines": { |       "engines": { | ||||||
|         "node": ">=4.0" |         "node": ">=4.0" | ||||||
|       }, |       }, | ||||||
| @ -3788,6 +3792,12 @@ | |||||||
|         "node": ">= 0.10" |         "node": ">= 0.10" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/proxy-from-env": { | ||||||
|  |       "version": "1.1.0", | ||||||
|  |       "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", | ||||||
|  |       "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|     "node_modules/ps-tree": { |     "node_modules/ps-tree": { | ||||||
|       "version": "1.2.0", |       "version": "1.2.0", | ||||||
|       "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", |       "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", | ||||||
| @ -4878,6 +4888,16 @@ | |||||||
|         "node": ">=12.0.0" |         "node": ">=12.0.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/wait-on/node_modules/axios": { | ||||||
|  |       "version": "0.27.2", | ||||||
|  |       "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", | ||||||
|  |       "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "follow-redirects": "^1.14.9", | ||||||
|  |         "form-data": "^4.0.0" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/webidl-conversions": { |     "node_modules/webidl-conversions": { | ||||||
|       "version": "3.0.1", |       "version": "3.0.1", | ||||||
|       "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", |       "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", | ||||||
|  | |||||||
| @ -24,6 +24,7 @@ | |||||||
|   "license": "MIT", |   "license": "MIT", | ||||||
|   "homepage": "https://bitbucket.org/online-mentor/multi-stub#readme", |   "homepage": "https://bitbucket.org/online-mentor/multi-stub#readme", | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|  |     "axios": "^1.7.7", | ||||||
|     "bcrypt": "^5.1.0", |     "bcrypt": "^5.1.0", | ||||||
|     "body-parser": "^1.19.0", |     "body-parser": "^1.19.0", | ||||||
|     "cookie-parser": "^1.4.5", |     "cookie-parser": "^1.4.5", | ||||||
|  | |||||||
							
								
								
									
										11
									
								
								server/routers/epja-2024-1/ecliptica/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								server/routers/epja-2024-1/ecliptica/index.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | const express = require('express'); | ||||||
|  | 
 | ||||||
|  | const plantsRouter = require('./plants/getPlants'); | ||||||
|  | const calendarRouter = require('./plants_calendar/index'); | ||||||
|  | 
 | ||||||
|  | const router = require('express').Router(); | ||||||
|  | 
 | ||||||
|  | module.exports = router; | ||||||
|  | 
 | ||||||
|  | router.use('/plants',plantsRouter) | ||||||
|  | router.use('/plants_calendar',calendarRouter) | ||||||
							
								
								
									
										6
									
								
								server/routers/epja-2024-1/ecliptica/plants/config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								server/routers/epja-2024-1/ecliptica/plants/config.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | |||||||
|  | const CONFIG = { | ||||||
|  |     CLIENT_ID: 'kD2JXj1faSCYAWdT4B069wQAx89CZAkXmzTinRvH', | ||||||
|  |     CLIENT_SECRET: 'bJq7Uiwua52tHiLP80N60hALNtQX2wcE4Mj6yNA9OzG2iZbgHuqyeAs6WSWX6MNJdfv0Nqzb7OHta8qPZr4zxWBLTauleaMfraln3xFEvbXLDpi1Lcrwe7DxfgsQQ1E4', | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | module.exports = CONFIG; | ||||||
							
								
								
									
										143
									
								
								server/routers/epja-2024-1/ecliptica/plants/getPlants.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								server/routers/epja-2024-1/ecliptica/plants/getPlants.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,143 @@ | |||||||
|  | const express = require ('express'); | ||||||
|  | const axios = require ('axios'); | ||||||
|  | const plantsRouter = express.Router (); | ||||||
|  | const CONFIG = require ('./config'); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | async function getAccessToken () { | ||||||
|  |   const formData = new FormData (); | ||||||
|  |   formData.append ('grant_type', 'client_credentials'); | ||||||
|  |   formData.append ('client_id', CONFIG.CLIENT_ID); | ||||||
|  |   formData.append ('client_secret', CONFIG.CLIENT_SECRET); | ||||||
|  | 
 | ||||||
|  |   try { | ||||||
|  |     const response = await axios.post ( | ||||||
|  |       'https://open.plantbook.io/api/v1/token/', | ||||||
|  |       formData, | ||||||
|  |       { | ||||||
|  |         headers: {'Content-Type': 'multipart/form-data'}, | ||||||
|  |       } | ||||||
|  |     ); | ||||||
|  |     if (response.data && response.data.access_token) { | ||||||
|  |       console.log ('Access token retrieved:', response.data.access_token); | ||||||
|  |       return response.data.access_token; | ||||||
|  |     } else { | ||||||
|  |       console.error ('Error: access_token not found in response'); | ||||||
|  |       return null; | ||||||
|  |     } | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error ( | ||||||
|  |       'Error fetching access token:', | ||||||
|  |       error.response ? error.response.data : error.message | ||||||
|  |     ); | ||||||
|  |     return null; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function fetchPlantData (plantId) { | ||||||
|  |   const accessToken = await getAccessToken (); | ||||||
|  |   if (!accessToken) { | ||||||
|  |     return null; | ||||||
|  |   } | ||||||
|  |   try { | ||||||
|  |     const response = await axios.get ( | ||||||
|  |       `https://open.plantbook.io/api/v1/plant/detail/${encodeURIComponent (plantId)}/`, | ||||||
|  |       { | ||||||
|  |         headers: { | ||||||
|  |           Authorization: `Bearer ${accessToken}`, | ||||||
|  |         }, | ||||||
|  |       } | ||||||
|  |     ); | ||||||
|  |     return response.data; | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error ( | ||||||
|  |       'Error fetching plant data:', | ||||||
|  |       error.response ? error.response.data : error.message | ||||||
|  |     ); | ||||||
|  |     return null; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | plantsRouter.get ('/list', async (req, res) => { | ||||||
|  |   const accessToken = await getAccessToken (); | ||||||
|  |   if (!accessToken) { | ||||||
|  |     res.status (500).send ({message: 'Error obtaining access token'}); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   try { | ||||||
|  |     const alias = req.query.alias || 'monstera'; | ||||||
|  |     const response = await axios.get ( | ||||||
|  |       'https://open.plantbook.io/api/v1/plant/search', | ||||||
|  |       { | ||||||
|  |         headers: { | ||||||
|  |           Authorization: `Bearer ${accessToken}`, | ||||||
|  |         }, | ||||||
|  |         params: { | ||||||
|  |           alias: alias, | ||||||
|  |         }, | ||||||
|  |       } | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const plantsList = response.data.results; | ||||||
|  | 
 | ||||||
|  |     const plants = await Promise.all ( | ||||||
|  |       plantsList.map (async plant => { | ||||||
|  |         const plantDetails = await fetchPlantData (plant.pid); | ||||||
|  |         return { | ||||||
|  |           id: plant.pid, | ||||||
|  |           alias: plant.alias, | ||||||
|  |           display_name: plant.display_name, | ||||||
|  |           image_url: plantDetails ? plantDetails.image_url : null, | ||||||
|  |           max_light: plantDetails ? plantDetails.max_light : null, | ||||||
|  |           min_light: plantDetails ? plantDetails.min_light : null, | ||||||
|  |           max_temp: plantDetails ? plantDetails.max_temp : null, | ||||||
|  |           min_temp: plantDetails ? plantDetails.min_temp : null, | ||||||
|  |           max_env_humid: plantDetails ? plantDetails.max_env_humid : null, | ||||||
|  |           min_env_humid: plantDetails ? plantDetails.min_env_humid : null, | ||||||
|  |           max_soil_moist: plantDetails ? plantDetails.max_soil_moist : null, | ||||||
|  |           min_soil_moist: plantDetails ? plantDetails.min_soil_moist : null, | ||||||
|  |           max_soil_ec: plantDetails ? plantDetails.max_soil_ec : null, | ||||||
|  |           min_soil_ec: plantDetails ? plantDetails.min_soil_ec : null, | ||||||
|  |         }; | ||||||
|  |       }) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     res.send ({results: plants}); | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error ( | ||||||
|  |       'Error fetching plant list:', | ||||||
|  |       error.response ? error.response.data : error.message | ||||||
|  |     ); | ||||||
|  |     res.status (500).send ({message: 'Error fetching plant list'}); | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | plantsRouter.get ('/:id', async (req, res) => { | ||||||
|  |   const plantId = req.params.id; | ||||||
|  |   const plantData = await fetchPlantData (plantId); | ||||||
|  | 
 | ||||||
|  |   if (plantData) { | ||||||
|  |     const detailedPlantData = { | ||||||
|  |       id: plantData.pid, | ||||||
|  |       display_name: plantData.display_name, | ||||||
|  |       alias: plantData.alias, | ||||||
|  |       max_light: plantData.max_light, | ||||||
|  |       min_light: plantData.min_light, | ||||||
|  |       max_temperature: plantData.max_temp, | ||||||
|  |       min_temperature: plantData.min_temp, | ||||||
|  |       max_humidity: plantData.max_env_humid, | ||||||
|  |       min_humidity: plantData.min_env_humid, | ||||||
|  |       max_soil_moisture: plantData.max_soil_moist, | ||||||
|  |       min_soil_moisture: plantData.min_soil_moist, | ||||||
|  |       max_soil_ec: plantData.max_soil_ec, | ||||||
|  |       min_soil_ec: plantData.min_soil_ec, | ||||||
|  |       image_url: plantData.image_url, | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     res.send (detailedPlantData); | ||||||
|  |   } else { | ||||||
|  |     res.status (404).send ({message: 'Plant not found'}); | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | module.exports = plantsRouter; | ||||||
| @ -0,0 +1,42 @@ | |||||||
|  | const express = require('express'); | ||||||
|  | 
 | ||||||
|  | const plantsRouter = express.Router() | ||||||
|  | 
 | ||||||
|  | const plants = [ | ||||||
|  |     { | ||||||
|  |         name: "Rose", | ||||||
|  |         image: "https://ervanarium.com.br/wp-content/uploads/2019/03/cactus-3142589_1920.jpg", | ||||||
|  |         frequency: 3, | ||||||
|  |         startDate: "2024-10-09", | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         name: "Sunflower", | ||||||
|  |         image: "https://avatars.mds.yandex.net/i?id=31da587c9aabc83ad3615023f91d7284781be06c-10701700-images-thumbs&n=13", | ||||||
|  |         frequency: 3, | ||||||
|  |         startDate: "2024-10-05", | ||||||
|  |     }, | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | const calculateWateringDates = (startDate, frequency) => { | ||||||
|  |     const dates = []; | ||||||
|  |     const start = new Date(startDate); | ||||||
|  | 
 | ||||||
|  |     for (let i = 0; i < 30; i += frequency) { | ||||||
|  |         const nextWateringDate = new Date(start); | ||||||
|  |         nextWateringDate.setDate(start.getDate() + i); | ||||||
|  |         dates.push(nextWateringDate.toISOString().split('T')[0]); | ||||||
|  |     } | ||||||
|  |     return dates; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | const plantsWithDates = plants.map(plant => ({ | ||||||
|  |     ...plant, | ||||||
|  |     wateringDates: calculateWateringDates(plant.startDate, plant.frequency), | ||||||
|  | })); | ||||||
|  | 
 | ||||||
|  | plantsWithDates.get('/api/plants', (req, res) => { | ||||||
|  |     res.json(plantsWithDates); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | module.exports = plantsRouter; | ||||||
| @ -1,9 +1,10 @@ | |||||||
| const express = require('express') | const express = require('express') | ||||||
| const router = express.Router() | const router = express.Router() | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| router.use('/enterfront', require('./enterfront/index')) | router.use('/enterfront', require('./enterfront/index')) | ||||||
| 
 | 
 | ||||||
| router.use('/cats', require('./cats/index')) | router.use('/cats', require('./cats/index')) | ||||||
| 
 | 
 | ||||||
|  | router.use('/ecliptica', require('./ecliptica/index')) | ||||||
|  | 
 | ||||||
| module.exports = router | module.exports = router | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user