From fd780b6e19436ce28a86f5141071e2f995f5942a Mon Sep 17 00:00:00 2001 From: Indrajith K L Date: Sat, 14 Aug 2021 01:55:16 +0530 Subject: * Adds Option to select States & Districts * Colored Texts --- find_session.v | 194 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 166 insertions(+), 28 deletions(-) diff --git a/find_session.v b/find_session.v index aebf2b4..c1250a7 100644 --- a/find_session.v +++ b/find_session.v @@ -2,8 +2,27 @@ import json import net.http import os import time +import term import term.ui as tui +struct StatesResponse { + states []State +} + +struct State { + state_id int + state_name string +} + +struct DistrictResponse { + districts []District +} + +struct District { + district_id int + district_name string +} + struct App { mut: tui &tui.Context = 0 @@ -16,8 +35,10 @@ struct VaccineAvailability { mut: date string available_sessions []Sessions - state_id int = 17 - district_id int = 296 + state_id int + district_id int + state State + district District } struct SessionResponse { @@ -74,7 +95,7 @@ fn frame(x voidptr) { } fn (mut app App) draw_header() { - app.tui.draw_text(3,2,"Vaccine Availability on ${app.data.date} | Total Centers : ${app.data.available_sessions.len}") + app.tui.draw_text(3,2, term.bold(term.bright_magenta("Vaccine Availability on ${app.data.date} | ${app.data.state.state_name},${app.data.district.district_name} | Total Centers : ${app.data.available_sessions.len}"))) app.tui.horizontal_separator(3) } @@ -83,15 +104,21 @@ fn (mut app App) draw_vaccine_availability() { start_x := 3 mut start_y := 5 if available_sessions.len == 0 { - app.tui.draw_text(app.tui.window_width/2 - 10,app.tui.window_height/2,"No Vaccine Available") + app.tui.draw_text(app.tui.window_width/2 - 10,app.tui.window_height/2, term.black(term.bg_white("No Vaccine Available"))) } else { for session in available_sessions { fee := match session.fee_type{ - 'Free' {'Free'} - 'Paid' { session.fee } + 'Free' {term.green('Free')} + 'Paid' {term.blue(session.fee) } else { 'N/A' } } - app.tui.draw_text(start_x,start_y,"${session.address} | Vaccine: ${session.vaccine} | Total Available: ${session.available_capacity} | Fee: ${fee}") + vaccine := match session.vaccine { + 'COVISHIELD' {term.bold(term.green(session.vaccine))} + 'COVAXIN' {term.bold(term.yellow(session.vaccine))} + else {session.vaccine} + } + capacity := term.green(session.available_capacity.str()) + app.tui.draw_text(start_x,start_y,"${session.name} | Vaccine: ${vaccine} | Total Available: ${capacity} | Fee: ${fee}") start_y += 2 } } @@ -102,29 +129,57 @@ fn init(x voidptr) { app.find_session(app.data.district_id, app.data.date) } - fn main() { - mut app := &App{} - app.tui = tui.init( - user_data: app - event_fn: event - frame_fn: frame - hide_cursor: false, - init_fn: init - ) - mut date_of_vaccine := time.now().add_days(app.idx).get_fmt_date_str(.hyphen,.ddmmyyyy) - if os.args.len ==2 { - date_of_vaccine = os.args[1] - } + setup_states() +} - println("Searching Vaccine Availability on $date_of_vaccine") - app.data.date = date_of_vaccine - app.tui.set_window_title("COWIN Vaccine Finder") - app.tui.run() ? +fn get_states() ?[]State { + fetch_config := http.FetchConfig{ + header: http.new_header( + key : .accept_language, + value: 'en-US' + ) + } + + url := 'https://cdn-api.co-vin.in/api/v2/admin/location/states' + resp := http.fetch(url, fetch_config) or { + term.clear() + println(term.fail_message('Failed to fetch States from the server')) + return error('Failed to fetch States from the server') + } + + states_data := json.decode(StatesResponse, resp.text) or { + term.clear() + println(term.fail_message('Failed to decode data from server')) + return error('Failed to decode data from server') + } + return states_data.states +} + +fn get_districts(state_id int) ?[]District { + fetch_config := http.FetchConfig{ + header: http.new_header( + key : .accept_language, + value: 'en-US' + ) + } + + url := 'https://cdn-api.co-vin.in/api/v2/admin/location/districts/$state_id' + resp := http.fetch(url, fetch_config) or { + term.clear() + println(term.fail_message('Failed to fetch Districts from the server')) + return error('Failed to fetch Districts from the server') + } + + district_data := json.decode(DistrictResponse, resp.text) or { + term.clear() + println(term.fail_message('Failed to decode data from server')) + return error('Failed to Decode data from the server') + } + return district_data.districts } fn (mut app App) find_session(district_id int,date string) { - app.is_loading = true fetch_config := http.FetchConfig{ header: http.new_header( key : .accept_language, @@ -140,14 +195,97 @@ fn (mut app App) find_session(district_id int,date string) { } session_data := json.decode(SessionResponse, resp.text) or { - println('failed to decode session json') + println(term.fail_message('Failed to decode data')) return } app.data.available_sessions = session_data.sessions.filter( it.available_capacity > 0 && it.min_age_limit<45) - app.is_loading = false } -fn setup_termui() { +fn setup_termui(state State, district District) { + mut app := &App{} + app.tui = tui.init( + user_data: app + event_fn: event + frame_fn: frame + hide_cursor: false, + init_fn: init + ) + mut date_of_vaccine := time.now().add_days(app.idx).get_fmt_date_str(.hyphen,.ddmmyyyy) + if os.args.len ==2 { + date_of_vaccine = os.args[1] + } + println("Searching Vaccine Availability on $date_of_vaccine") + app.data.date = date_of_vaccine + app.data.state = state + app.data.district = district + app.data.state_id = state.state_id + app.data.district_id = district.district_id + app.tui.set_window_title("COWIN Vaccine Finder") + app.tui.run() or {} +} + +fn setup_states() { + term.clear() + width, height := term.get_terminal_size() + println(term.header('Available State', '=')) + start_x := width/2 - 10 + mut start_y := 5 + mut selected_state := 0 + term.set_cursor_position(x: start_x, y: start_y) + + states := get_states() or { + return + } + + for i in 0 .. states.len { + println(term.bright_green('$i . ${states[i].state_name}')) + start_y += 1 + term.set_cursor_position(x: start_x, y: start_y) + } + term.set_cursor_position(x: 0, y: height) + + for { + if var := os.input_opt('Please select a State: ') { + if var.int() < 0 || var.int() >= states.len { + continue + } + setup_districts(states[var.int()]) + break + } + println('') + break + } + +} + +fn setup_districts(state State) { + term.clear() + width, height := term.get_terminal_size() + println(term.header('Available States', '=')) + start_x := width/2 - 10 + mut start_y := 5 + term.set_cursor_position(x: start_x, y: start_y) + districts := get_districts(state.state_id) or { + return + } + + for i in 0 .. districts.len { + println(term.bright_green('$i . ${districts[i].district_name}')) + start_y += 1 + term.set_cursor_position(x: start_x, y: start_y) + } + term.set_cursor_position(x: 0, y: height) + for { + if var := os.input_opt('Please select a District: ') { + if var.int() < 0 || var.int() >= districts.len { + continue + } + setup_termui(state,districts[var.int()]) + break + } + println('') + break + } } \ No newline at end of file -- cgit v1.2.3