Skip to content

Commit

Permalink
add files
Browse files Browse the repository at this point in the history
  • Loading branch information
SaifulI57 committed Feb 3, 2024
0 parents commit 280dca7
Show file tree
Hide file tree
Showing 10 changed files with 1,463 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
41 changes: 41 additions & 0 deletions api/controller/fetch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import fs from 'fs'
import { dom, getUpdates } from '../../getData.js'

let updated
let files
let fjson = {}
let date = new Date()
let updateFiles = async ()=>{
console.log('[0] getting info')
files = fs.readFileSync('api/data/allforecast.json')
}
let toJson = async ()=>{
fjson = JSON.parse(files)
}
let lastupdate

try{
// console.log('here')
updated = await getUpdates()
if(date.getHours() >= 9 && date.getHours() <= 11){
if(fjson.provinsijawatimur.datetime === lastupdate){
console.log('[0] updated')
}
await updateFiles()
console.log('[0] waiting 10mnt for the next update...')
await new Promise((res,rej)=> console.log('[0] timeout 10mnt'),600000)
}
if(Object.keys(fjson).length === 0) throw new Error('no obj found')
}catch(e){
console.log('[0] init obj')
await updateFiles()
await toJson()
console.log('[0] last update on', fjson.provinsijawatimur.datetime)
lastupdate = fjson.provinsijawatimur.datetime
if(lastupdate !== updated){
await updateFiles()
}
}


export default fjson
1 change: 1 addition & 0 deletions api/data/allforecast.json

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions api/routes/regency.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import fjson from '../controller/fetch.js'


let getRegency = (req,res)=>{
let q = req.params
let rege = new RegExp(q.kabupaten)
let prov = new RegExp(q.provinsi)
let data = {}
let result = {}
Object.keys(fjson).forEach(key=>{
if(prov.test(key)){
data = fjson[key]
}
})
Object.keys(data.kab).forEach(key=>{
if(rege.test(key)){
result = data.kab[key]
}
})
res.send(result)
}

export default getRegency
17 changes: 17 additions & 0 deletions api/routes/region.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import fjson from '../controller/fetch.js'

const getRegion = (req, res) => {
let slug = req.params
let re = new RegExp(slug.kota)
let data = {}
Object.keys(fjson).forEach(key =>{
console.log(re.test(key))
if(re.test(key)){
data = fjson[key]
}
})
res.send(data)
};


export default getRegion
9 changes: 9 additions & 0 deletions api/weather.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Router } from "express";
import getRegion from './routes/region.js'
import getRegency from "./routes/regency.js";
const apiRoutes = Router();

apiRoutes.get("/region/:kota", getRegion);
apiRoutes.get("/region/:provinsi/regency/:kabupaten", getRegency)

export default apiRoutes
165 changes: 165 additions & 0 deletions getData.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import { DOMParser } from 'xmldom'
import fs from 'fs'
import { JSDOM as a } from 'jsdom'
let parser = new DOMParser()
let url = 'https://data.bmkg.go.id/prakiraan-cuaca/'
let dom = new a()
let allForcast= {}
let getUpdate = async ()=>{
await fetch(url,{ Headers: { 'Content-Type': 'text/html' },Method: 'get'})
.then(resp => resp.text())
.then(text => new a(text))
.then(data => dom = data.window.document.getElementsByTagName('tr'))
}
let getUpdates = async ()=>{
let datas
await fetch(url,{ Headers: { 'Content-Type': 'text/html' },Method: 'get'})
.then(resp => resp.text())
.then(text => new a(text))
.then(data => {datas = data.window.document.getElementsByTagName('tr')[1].cells[3].textContent})
return datas
}
let getAllArea = (data)=>{
let obj = {}
for(let i = 0; i < data.length;i++){
let desc = data[i].getAttribute('description')
let formated = desc.replaceAll(' ','').toLowerCase()
obj[formated] = getAllAttrParameter(data[i].getElementsByTagName('parameter'))
}
return obj
}
let getAttributeTimerange = (data, iterate)=>{
let temp = []
for(let i = 0; i < data[iterate].getElementsByTagName('value').length;i++){
temp.push({'value': data[iterate].getElementsByTagName('value')[i].textContent,'unit':data[iterate].getElementsByTagName('value')[i].getAttribute('unit')})
}
let type = data[iterate].getAttribute('type')
let format = type === 'daily'? {'daily':data[iterate].getAttribute('day')} : {'hour':data[iterate].getAttribute('h')}
return {
'data':temp,
'type': type,
'time': format,
'datetime': data[iterate].getAttribute('datetime')
}
}

let getAllAttrParameter = (data)=>{
let params = {}
let attr = {}
for(let i = 0; i < data.length;i++){
let desc = data[i].getAttribute('id')
for(let j = 0; j < data[i].getElementsByTagName('timerange').length;j++){
let parseTime = data[i].getElementsByTagName('timerange')[j].getAttribute('type') === 'hourly' ? data[i].getElementsByTagName('timerange')[j].getAttribute('h') : data[i].getElementsByTagName('timerange')[j].getAttribute('day').split('')[data[i].getElementsByTagName('timerange')[j].getAttribute('day').length-2].concat(data[i].getElementsByTagName('timerange')[j].getAttribute('day')[data[i].getElementsByTagName('timerange')[j].getAttribute('day').length-1])
attr[parseTime] = getAttributeTimerange(data[i].getElementsByTagName('timerange'),j)
}
params[desc] = attr
attr = {}
}

return params
}

let getAllForecast = async ()=>{
let formatDate = {}
for(let i = 1; i < dom.length; i++){
let datePath = dom[i].cells[3].textContent
let arr = datePath.replace(',','').split(' ')
formatDate[dom[i].cells[1].textContent.replaceAll(' ','').toLowerCase()] = {
'name': dom[i].cells[1].textContent.replaceAll(' ','').toLowerCase(),
'path': dom[i].cells[2].textContent,
'datetime': datePath,
'day': arr[0],
'month': arr[1],
'year': arr[2],
'hour': arr[3].split(':')[0],
'minute': arr[3].split(':')[1],
'second': arr[3].split(':')[2],
'zone': arr[4]
}
}
let fetching = async (p,d)=>{
let obj = {}
await fetch(`https://data.bmkg.go.id/DataMKG/MEWS/DigitalForecast/${p}`,{headers: {'Content-Type': 'text/xml'},method: 'GET'})
.then(response => response.text())
.then(str => parser.parseFromString(str, 'text/xml'))
.then(data => {
let forecast = data.documentElement.getElementsByTagName('area')
obj = {
...d,
'kab': getAllArea(forecast)
}
})
return obj
}

let insr = async ()=>{
let er = []
Object.keys(formatDate).forEach(data => {
er.push(data)
})

let rec = async (i) =>{
if(i === er.length){
fs.writeFileSync('api/data/allforecast.json', JSON.stringify(allForcast))
console.log('[1] updated')
start()
}else{
allForcast[er[i]] = await fetching(formatDate[er[i]].path,formatDate[er[i]])
rec(i+1)
}
}
console.log('[1] getting all data forecast today')
await new Promise((res,rej)=> rec(0))
}
await insr()
}

let start = async () => {
let date = new Date()
let update = false
let files = fs.readFileSync('api/data/allforecast.json')
files = JSON.parse(files)
await getUpdate()
let lastUpdate = Object.keys(allForcast).length > 0 ? allForcast.provinsiaceh.datetime : files.provinsiaceh.datetime
while(true){
try{
if(update === true){
let starts = await getAllForecast()
await starts.init()
continue
}
if(dom[1].cells[3].textContent === lastUpdate){
update = false
if(date.getHours() > 11 || date.getHours() < 7){
await new Promise((res,rej)=> {
console.log('[1] jeda 2 jam')
setTimeout(res, 7200000,()=> console.log('[1] timeout 2 hour'))
})
}
}else if(date.getHours() >= 9 || date.getHours() <= 13){
console.log('[1] check if there is an update available')
await getUpdate()
await new Promise((res,rej)=> {
console.log('[1] waiting 10 minute before next check')
setTimeout(res, 600000,()=> console.log('[1] timeout 10mnt'))
})
if(lastUpdate !== dom[1].cells[3].textContent){
update = true
console.log('[1] Data Updated')
}

}
}catch(e){
console.log('[1] initialize')
await getUpdate()
console.log('[1] done')
update = true
}

}


}
start()

export { start, getUpdates, dom}
Loading

0 comments on commit 280dca7

Please sign in to comment.