Skip to content

Commit

Permalink
[New Feature] Multi language translation #3
Browse files Browse the repository at this point in the history
  • Loading branch information
cecy07 committed Sep 19, 2023
1 parent 4db2a9f commit 0e41b18
Show file tree
Hide file tree
Showing 7 changed files with 833 additions and 71 deletions.
161 changes: 92 additions & 69 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import subprocess
import sys
from copy import deepcopy

import gettext
_ = gettext.gettext
import pandas as pd
import streamlit as st
from st_aggrid import AgGrid, GridOptionsBuilder
Expand All @@ -12,6 +13,23 @@
from ktrains.srt.srt import SRT
from ktrains.utils import Stations, save_to_log, LINKS

language = st.sidebar.selectbox(_('Select your language'), ['English', '한국어', 'Italiano','Español'])
if language == 'English':
language = 'en'
elif language == '한국어':
language = 'kr'
elif language == 'Español':
language = 'es'
elif language == 'Italiano':
language = 'it'

try:
localizator = gettext.translation('base', localedir='locales', languages=[language])
localizator.install()
_ = localizator.gettext
except:
pass

# Dictionary of functions
name_to_class = {
"korail": Korail,
Expand Down Expand Up @@ -53,25 +71,23 @@ def check_login():
return True
return False


st.title("K-trains 🇰🇷-🚄")

st.write(f"Fork me on [GitHub]{LINKS['app']['github']}")
st.markdown(_("Fork me on:") + f" [{_('GitHub')}]({LINKS['app']['github']})")

if not check_login():
# Login page
# Checkbox with two options and an image on top of each
mode = st.selectbox("Select railways company", ["Korail", "SRT"]).lower()
mode = st.selectbox(_("Select railways company"), [_("Korail"), _("SRT")]).lower()
st.session_state.mode = mode.lower()
st.write(
"Get your credentials from {} website: [{}]({})".format(
st.write(_(
"Get your credentials from {} website: [{}]({})").format(
LINKS[mode]["name"], LINKS[mode]["link"], LINKS[mode]["link"]
)
)
col1, col2 = st.columns(2)
st.session_state.id = col1.text_input("ID", st.session_state.id)
st.session_state.pw = col2.text_input("PW", st.session_state.pw, type="password")
login_button = st.button("Login")
st.session_state.id = col1.text_input(_("ID"), st.session_state.id)
st.session_state.pw = col2.text_input(_("PW"), st.session_state.pw, type="password")
login_button = st.button(_("Login"))
if login_button:
KTrains = name_to_class[st.session_state.mode]
ktrains = KTrains(st.session_state.id, st.session_state.pw, auto_login=True)
Expand All @@ -80,22 +96,24 @@ def check_login():
# refresh page
st.experimental_rerun()
else:
st.error("Login failed")
st.error(_("Login failed"))
else:
language = st.selectbox("Select language", ["en", "kor"])
if language == 'kr':
language_sched = 'kor'
else:
language_sched = 'en'

# What happens when logged in
mode = st.session_state.mode

stations = Stations(mode, language)
stations = Stations(mode, language_sched)

# Login and logout
st.success("Logged in successfully to {}".format(mode.upper()))
st.success(_("Logged in successfully to {}").format(mode.upper()))
col1, col2 = st.columns(2)
with col1:
st.write("Logged in as: {}".format(st.session_state.id))
st.write(_("Logged in as: {}").format(st.session_state.id))
with col2:
logout_button = st.button("Logout")
logout_button = st.button(_("Logout"))
if logout_button:
st.session_state.ktrains.logout()
st.session_state.ktrains = None
Expand All @@ -109,10 +127,10 @@ def check_login():
# Set with two columns
col1, col2 = st.columns(2)
dep = col1.selectbox(
"Departure", stations.station_names(), index=107 if mode == "korail" else 0
_("Departure"), stations.station_names(), index=107 if mode == "korail" else 0
)
arr = col2.selectbox(
"Arrival", stations.station_names(), index=44 if mode == "korail" else 5
_("Arrival"), stations.station_names(), index=44 if mode == "korail" else 5
)
dep = stations.convert_station_name(dep)
arr = stations.convert_station_name(arr)
Expand All @@ -125,20 +143,26 @@ def check_login():
date = date.strftime("%Y%m%d")
time = time.strftime("%H%M%S")

if st.button("Search"):
table_stations = Stations(mode,language_sched)
if st.button(_("Search")):
trains = ktrains.search_train(dep, arr, date, time, available_only=False)
if trains == []:
st.error("No trains found")
st.session_state.trains = None
else:
#stations.convert_station_name(trains[0].dep_station_name, lang="en")
train_list = []
for train in trains:
if language != 'kr':
table_lang = "tc"
else:
table_lang = "kr"
train_list.append(
{
"train_no": train.train_number,
"train_type_name": train.train_name,
"dep_name": train.dep_station_name,
"arr_name": train.arr_station_name,
"train_type_name": stations.convert_train_name(train.train_name,lang=table_lang),
"dep_name": stations.convert_station_name(train.dep_station_name,lang=table_lang),
"arr_name": stations.convert_station_name(train.arr_station_name,lang=table_lang),
"dep_time": train.dep_time,
"arr_time": train.arr_time,
"duration": None,
Expand Down Expand Up @@ -188,13 +212,13 @@ def check_login():
df = df.iloc[:, [0, 1, 4, 5, 2, 6, 3]]

df.columns = [
"No",
"Type",
"Schedule",
"Time",
"Duration",
"Normal/Special Seat",
"Price",
_("No"),
_("Type"),
_("Schedule"),
_("Time"),
_("Duration"),
_("Normal/Special Seat"),
_("Price"),
]

gd = GridOptionsBuilder.from_dataframe(df)
Expand All @@ -206,7 +230,7 @@ def check_login():
date = st.session_state.search_date
if date is not None:
date_formatted = date[:4] + "/" + date[4:6] + "/" + date[6:]
st.write("Search results for {}:".format(date_formatted))
st.write(_("Search results for {}:").format(date_formatted))

grid_return = AgGrid(
df,
Expand All @@ -218,7 +242,7 @@ def check_login():
header_checkbox_selection_filtered_only=True,
theme="streamlit",
use_checkbox=True,
width="200%",
width="200%"
)

new_df = pd.DataFrame(grid_return["selected_rows"])
Expand All @@ -228,70 +252,69 @@ def check_login():
train_codes = new_df["No"].tolist()
# st.write(train_codes)

st.header("Runner Settings")
st.write(
st.header(_("Runner Settings"))
st.write(_(
"The app will automatically reserve and/or notify you when the train is available."
)
))

col1, col2 = st.columns(2)
with col1:
st.subheader("Reserve settings")
st.write(
f"Reserve the train(s) automatically. You will need to reserve in the app/website within few minutes [here]({LINKS[mode]['reserve_link']})"
)
st.write(
st.subheader(_("Reserve settings"))
st.markdown(_(
"Reserve the train(s) automatically. You will need to reserve in the app/website within a few minutes.")+ f" ([link]({LINKS[mode]['reserve_link']}))"
)

st.write(_(
"If you do not process the payment, the reservation will be cancelled automatically."
)
))
st.number_input(
"Number of tickets",
_("Number of tickets"),
min_value=1,
max_value=10,
value=1,
step=1,
key="num_tickets",
)

st.write(
"Select the prefered seat type. If both are selected, the app will try to reserve the first available."
)
st.write(_("Please select the preferred seat type. If both are selected, the app will try to reserve the first available."))
sub_col1, sub_col2 = st.columns(2)
with sub_col1:
general_seat = st.checkbox("General seat", key="general_seat", value=True)
general_seat = st.checkbox(_("General seat"), key="general_seat", value=True)
with sub_col2:
special_seat = st.checkbox("Special seat", key="special_seat", value=True)
special_seat = st.checkbox(_("Special seat"), key="special_seat", value=True)
if general_seat and not special_seat:
seat_type = "R"
elif not general_seat and special_seat:
seat_type = "S"
else:
seat_type = "B"
with col2:
st.subheader("Email notifications settings")
st.write("Notify you when the train is available.")
st.write(
st.subheader(_("Email notifications settings"))
st.write(_("Notify you when the train is available."))
st.write(_(
"Receivers are the email addresses that will receive notifications. Use commas to separate multiple addresses."
)
st.write(
f"Note: sender email is {LINKS['app']['email']}. Be sure to check your spam folder."
)
email_receivers = st.text_input("Receivers", st.session_state.email_receivers)
))
st.write(_(
"Note: sender email is ")+f" {LINKS['app']['email']} ."+_(" Be sure to check your spam folder."
))
email_receivers = st.text_input(_("Receivers"), st.session_state.email_receivers)
st.session_state.email_receivers = email_receivers

col1, col2 = st.columns(2)
with col1:
st.write("Check to reserve the ticket.")
st.checkbox("Reserve", key="reserve", value=True)
st.write(_("Check to reserve the ticket."))
st.checkbox(_("Reserve"), key="reserve", value=True)
with col2:
st.write("Check to Notify to email.")
st.checkbox("Notify", key="notify", value=True)
st.write(_("Check to Notify to email."))
st.checkbox(_("Notify"), key="notify", value=True)

st.markdown("---")

if st.button("Submit"):
if st.button(_("Submit")):
if email_receivers == "" and st.session_state.notify:
st.error("Please set receiver(s) email in the sidebar")
st.error(_("Please set receiver(s) email in the sidebar"))
elif new_df.empty:
st.error("Please select at least one train")
st.error(_("Please select at least one train"))
else:
# Run as a subprocess
# make train codes to string with comma
Expand Down Expand Up @@ -331,15 +354,15 @@ def check_login():
st.session_state.running = True
st.session_state.pid = pid
save_to_log("") # clear log
st.write("Running...")
st.write(_("Running..."))

# If running, show log
if st.session_state.running:
st.write(
st.write(_(
"Hang tight, I'm running... This may take some time, until we find a train!"
)
))
st.markdown("---")
st.write("Log:")
st.write(_("Log:"))
with open("log.txt", "r") as f:
log = f.read()
if st.session_state.previous_log != log:
Expand All @@ -348,10 +371,10 @@ def check_login():

# Stop runner
st.markdown("---")
if st.button("Stop runner"):
if st.button(_("Stop runner")):
if st.session_state.pid is not None:
st.session_state.pid.terminate()
st.success("Stopped")
st.success(_("Stopped"))
st.session_state.running = False
else:
st.error("No process running")
st.error(_("No process running"))
44 changes: 42 additions & 2 deletions ktrains/korail/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -532,16 +532,56 @@
"Hwanggan",
"Hoengseong",
"Hoengcheon",
" Hyocheon",
"Hyocheon",
]

station_names = {"kor": station_names_korean, "en": station_names_english}


def convert_station_name(station_name, lang="en"):
if lang == "en":
# get index of station_name in station_names_english
index = station_names_english.index(station_name)
return station_names_korean[index]
elif lang == "tc":
index = station_names_korean.index(station_name)
return station_names_english[index]
else:
return station_name


train_types_korean = [
"KTX",
"KTX-산천",
"ITX-청춘",
"ITX-마음",
"ITX-새마을",
"새마을",
"누리로",
"무궁화호",
"통근열차",
]

train_types_english = [
"KTX",
"KTX-Sancheon",
"ITX-Cheongchun",
"ITX-Maum",
"ITX-Saemaeul",
"Saemaeul",
"Nuriro",
"Mugunghwa",
"Commuter",
]

train_types = {"kor": train_types_korean, "en": train_types_english}

def convert_train_name(train_type, lang):
if lang == "en":
index = train_types_english.index(train_type)
return train_types_korean[index]
elif lang == "tc":
index = train_types_korean.index(train_type)
return train_types_english[index]
else:
return train_type

3 changes: 3 additions & 0 deletions ktrains/srt/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,8 @@ def convert_station_name(station_name, lang="en"):
# get index of station_name in station_names_english
index = station_names_english.index(station_name)
return station_names_korean[index]
elif lang == "tc":
index = station_names_korean.index(station_name)
return station_names_english[index]
else:
return station_name
Loading

0 comments on commit 0e41b18

Please sign in to comment.