11// @flow
22import { loadLoginCredentials } from '../login'
33import buildFormData from '../formdata'
4- import { parseHtml , cssSelect , getTrimmedTextWithSpaces } from '../html'
5- import { OLECARD_AUTH_URL } from './urls'
6- import type { BalancesShapeType } from './types'
7- import fromPairs from 'lodash/fromPairs'
4+ import { OLECARD_AUTH_URL , OLECARD_DATA_ENDPOINT } from './urls'
5+ import type { BalancesShapeType , OleCardBalancesType } from './types'
86import isNil from 'lodash/isNil'
97import * as cache from '../cache'
108
@@ -22,6 +20,7 @@ export async function getBalances(
2220 print,
2321 daily,
2422 weekly,
23+ plan,
2524 _isExpired,
2625 _isCached,
2726 } = await cache . getBalances ( )
@@ -46,6 +45,7 @@ export async function getBalances(
4645 print : print . value ,
4746 daily : daily . value ,
4847 weekly : weekly . value ,
48+ plan : plan . value ,
4949 } ,
5050 }
5151}
@@ -60,70 +60,44 @@ async function fetchBalancesFromServer(): Promise<BalancesOrErrorType> {
6060 username : username ,
6161 password : password ,
6262 } )
63- const result = await fetch ( OLECARD_AUTH_URL , { method : 'POST' , body : form } )
64- const page = await result . text ( )
65- const dom = parseHtml ( page )
63+ await fetch ( OLECARD_AUTH_URL , { method : 'POST' , body : form } )
6664
67- return parseBalancesFromDom ( dom )
65+ const resp : OleCardBalancesType = await fetchJson ( OLECARD_DATA_ENDPOINT )
66+
67+ return getBalancesFromData ( resp )
6868}
6969
70- function parseBalancesFromDom ( dom : mixed ) : BalancesOrErrorType {
71- // .accountrow is the name of the row, and it's immediate sibling is a cell with id=value
72- const elements = cssSelect ( '.accountrow' , dom )
73- . map ( el => el . parent )
74- . map ( getTrimmedTextWithSpaces )
75- . map ( rowIntoNamedAmount )
76- . filter ( Boolean )
70+ const accounts = {
71+ flex : 'STO Flex' ,
72+ ole : 'STO Ole Dollars' ,
73+ print : 'STO Student Printing' ,
74+ }
7775
78- const namedValues = fromPairs ( elements )
76+ function getBalancesFromData ( resp : OleCardBalancesType ) : BalancesOrErrorType {
77+ if ( resp . error ) {
78+ return {
79+ error : true ,
80+ value : new Error ( resp . error ) ,
81+ }
82+ }
7983
80- const flex = dollarAmountToInteger ( namedValues . flex )
81- const ole = dollarAmountToInteger ( namedValues . ole )
82- const print = dollarAmountToInteger ( namedValues . print )
83- const daily = namedValues . daily
84- const weekly = namedValues . weekly
84+ const flex = resp . data . accounts . find ( a => a . account === accounts . flex )
85+ const ole = resp . data . accounts . find ( a => a . account === accounts . ole )
86+ const print = resp . data . accounts . find ( a => a . account === accounts . print )
87+
88+ const daily = resp . data . meals && resp . data . meals . leftDaily
89+ const weekly = resp . data . meals && resp . data . meals . leftWeekly
90+ const plan = resp . data . meals && resp . data . meals . plan
8591
8692 return {
8793 error : false ,
8894 value : {
89- flex : isNil ( flex ) ? null : flex ,
90- ole : isNil ( ole ) ? null : ole ,
91- print : isNil ( print ) ? null : print ,
95+ flex : flex || flex === 0 ? flex . formatted : null ,
96+ ole : ole || ole === 0 ? ole . formatted : null ,
97+ print : print || print === 0 ? print . formatted : null ,
9298 daily : isNil ( daily ) ? null : daily ,
9399 weekly : isNil ( weekly ) ? null : weekly ,
100+ plan : isNil ( plan ) ? null : plan ,
94101 } ,
95102 }
96103}
97-
98- const lookupHash : Map < RegExp , string > = new Map ( [
99- [ / s t o f l e x / i, 'flex' ] ,
100- [ / o l e / i, 'ole' ] ,
101- [ / p r i n t / i, 'print' ] ,
102- [ / m e a l s .* d a y / i, 'daily' ] ,
103- [ / m e a l s .* w e e k / i, 'weekly' ] ,
104- ] )
105-
106- function rowIntoNamedAmount ( row : string ) : ?[ string , string ] {
107- const chunks = row . split ( ' ' )
108- const name = chunks . slice ( 0 , - 1 ) . join ( ' ' )
109- const amount = chunks [ chunks . length - 1 ]
110-
111- // We have a list of regexes that check the row names for keywords.
112- // Those keywords are associated with the actual key names.
113- for ( const [ lookup , key ] of lookupHash . entries ( ) ) {
114- if ( lookup . test ( name ) ) {
115- return [ key , amount ]
116- }
117- }
118- }
119-
120- function dollarAmountToInteger ( amount : ?string ) : ?number {
121- const amountString = amount || ''
122- // remove the /[$.]/, and put the numbers into big strings (eg, $3.14 -> '314')
123- const nonDenominationalAmount = amountString
124- . replace ( '$' , '' )
125- . split ( '.' )
126- . join ( '' )
127- const num = parseInt ( nonDenominationalAmount , 10 )
128- return Number . isNaN ( num ) ? null : num
129- }
0 commit comments