1
+ const axios = require ( 'axios' ) ;
2
+ const https = require ( 'https' )
3
+
4
+ const Period = {
5
+ Today : 'today' ,
6
+ Week : 'week' ,
7
+ Month : 'month' ,
8
+ Year : 'year' ,
9
+ Duration : 'duration'
10
+ }
11
+
12
+ const getZones = ( ) => {
13
+ return new Promise ( ( resolve , reject ) => {
14
+ const url = "https://www.e-solat.gov.my/index.php?siteId=24&pageId=24" ;
15
+ https . get ( url , ( res ) => {
16
+ let result = '' ;
17
+ res . on ( 'data' , ( chunk ) => {
18
+ result += chunk ;
19
+ } ) ;
20
+ res . on ( 'end' , ( ) => {
21
+ const pattern = / < s e l e c t i d = " i n p u t Z o n e " c l a s s = " f o r m - c o n t r o l " > ( [ \w \W ] * ?) < \/ s e l e c t > / ;
22
+ const matches = result . match ( pattern ) ;
23
+ const pattern2 = / < o p t g r o u p ( [ \w \W ] * ?) < \/ o p t g r o u p > / g;
24
+ const stateJson = matches [ 1 ] . match ( pattern2 ) . reduce ( ( acc , zone ) => {
25
+ const statePattern = / l a b e l = " ( [ \w \W ] * ?) " / ;
26
+ const state = zone . match ( statePattern ) [ 1 ] ;
27
+
28
+ const zonePattern = / < o p t i o n .* ?v a l u e = ' ( [ \w \W ] * ?) ' .* ?> ( [ \w \W ] * ?) < \/ o p t i o n > / g;
29
+ const zonJson = Array . from ( zone . matchAll ( zonePattern ) ) . reduce ( ( acc , matches ) => {
30
+ const zonecode = matches [ 1 ] ;
31
+ const zonename = matches [ 2 ] . replace ( / < \/ ? [ ^ > ] + ( > | $ ) / g, '' ) . split ( " - " ) [ 1 ] ;
32
+ acc [ zonecode ] = zonename ;
33
+ return acc ;
34
+ } , { } ) ;
35
+
36
+ acc [ state ] = zonJson ;
37
+ return acc ;
38
+ } , { } ) ;
39
+
40
+ resolve ( stateJson ) ;
41
+ } ) ;
42
+ } ) . on ( 'error' , ( err ) => {
43
+ reject ( new Error ( err . message ) ) ;
44
+ } ) ;
45
+ } ) ;
46
+ } ;
47
+
48
+
49
+
50
+
51
+ const parseQuery = async ( period , zone ) => {
52
+ if ( typeof period !== 'string' || typeof zone !== 'string' ) throw new Error ( 'period or zone must be a string' )
53
+
54
+ if ( ! Object . values ( Period ) . includes ( period ) ) throw new Error ( 'period must be one of today, week, month, year, duration' )
55
+
56
+ let zones
57
+
58
+ await getZones ( ) . then ( ( stateJson ) => {
59
+ zones = stateJson
60
+ } ) . catch ( ( err ) => {
61
+ console . error ( err ) ;
62
+ } ) ;
63
+
64
+ const stateKeys = Object . values ( zones ) . map ( i => Object . keys ( i ) ) . reduce ( ( acc , curr ) => [ ...acc , ...curr ] , [ ] )
65
+ if ( ! stateKeys . includes ( zone ) ) throw new Error ( 'invalid state key' )
66
+
67
+ return {
68
+ period,
69
+ zone
70
+ }
71
+ }
72
+
73
+ const getPrayerTimes = async ( period = Period . Today , zone ) => {
74
+ await parseQuery ( period , zone )
75
+ const url = `https://www.e-solat.gov.my/index.php?r=esolatApi/takwimsolat&period=${ period } &zone=${ zone } ` ;
76
+ const res = await axios . post ( url ,
77
+ { datestart : 'YYYY-MM-DD' , dateend : 'YYYY-MM-DD' }
78
+ ) . then ( response => response . data )
79
+ . catch ( error => console . error ( error ) ) ;
80
+ return res
81
+ }
82
+
83
+ module . exports = {
84
+ Period,
85
+ parseQuery,
86
+ getPrayerTimes,
87
+ getZones
88
+ }
0 commit comments