Skip to content

Commit

Permalink
Add multiselect interactive menu
Browse files Browse the repository at this point in the history
  • Loading branch information
yankeexe committed Feb 1, 2022
1 parent 372ffef commit 62bd87f
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 44 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

setuptools.setup(
name="timezones_cli",
version="0.2.14",
version="0.3.0",
author="Yankee Maharjan",
url="https://github.com/yankeexe/timezones-cli",
description="Get local datetime from multiple timezones!",
Expand Down
45 changes: 33 additions & 12 deletions timezones_cli/commands/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,29 @@

import click

from timezones_cli.utils import check_config, console, validate_timezone, variables
from timezones_cli.utils import (
check_config,
console,
handle_interaction,
query_handler,
variables,
)


@click.command()
@click.argument("timezone")
def add(timezone: str):
@click.argument("query")
def add(query: str):
"""
Add timezone to the config file.
"""
validate_timezone(timezone)
added_timezones = []
existing_timezones = []
line_break = "\n"
timezones = query_handler(query)

if len(timezones) > 1:
timezones = handle_interaction(timezones)

config_file = variables.config_file

if not check_config():
Expand All @@ -25,16 +38,24 @@ def add(timezone: str):
with open(config_file, "r+") as file:
data: List = [line.rstrip() for line in file]

if timezone in data:
return console.print(
f"[bold green]Timezone already exists:[/bold green] [bold red]{timezone}:x:[/bold red]"
for timezone in timezones:
if timezone in data:
existing_timezones.append(f"[bold red]{timezone}:x:[/bold red]")
continue

file.read()
# Add to the end of the file.
file.write(f"{timezone}\n")
added_timezones.append(
f"[bold blue]{timezone}[/bold blue] :white_check_mark:"
)

# Read file
file.read()
if existing_timezones:
console.print(
f"[bold yellow]Timezone/s already exists:[/bold yellow]\n{line_break.join(existing_timezones)}"
)

# Add to the end of the file.
file.write(f"{timezone}\n")
if added_timezones:
console.print(
f"[bold green]New timezone added successfully:[/bold green] [bold blue]{timezone}[/bold blue] :white_check_mark:"
f"[bold green]New timezone/s added successfully:[/bold green]\n{line_break.join(added_timezones)}"
)
6 changes: 2 additions & 4 deletions timezones_cli/commands/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,12 @@ def search(query: str, toggle: bool):
"""
try:
result = query_handler(query)
payload: t.List = []

# If length is greater than one, show terminal menu.
if isinstance(result, t.List) and len(result) > 1:
entry = handle_interaction(result)
entries = handle_interaction(result)

payload.append(entry)
return get_local_time(payload, toggle=toggle)
return get_local_time(entries, toggle=toggle)
except LookupError:
return console.print(
"Couldn't resolve your query, please try other keywords.:x:"
Expand Down
7 changes: 3 additions & 4 deletions timezones_cli/commands/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,13 @@ def select(toggle: bool):
$ tz select
"""
config_file = variables.config_file
entry = []

with open(config_file, "r+") as file:
data = [line.rstrip() for line in file]

if not len(data):
if not data:
return console.print("Config file contains no timezone:x:")

entry.append(handle_interaction(data))
entries = handle_interaction(data)

return get_local_time(entry, toggle=toggle)
return get_local_time(entries, toggle=toggle)
67 changes: 44 additions & 23 deletions timezones_cli/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,67 +42,85 @@ def remove_timezone(interactive: bool, name: Optional[str] = None):
"""
config_file: str = variables.config_file
entry: Optional[str]
removed_timezones = []
add_prompt = "Use `tz add` to create and add timezone to your config file.:memo:"

if not check_config():
console.print(
"No configuration file found in your system.:x:\n",
style="bold red",
)
console.print(
"Use `tz add` to create and add timezone to your config file.:memo:",
style="bold green",
)
console.print(add_prompt, style="bold green")
sys.exit()

with open(config_file, "r+") as file:
data: List = [line.rstrip() for line in file]

if not len(data):
if not data:
console.print("Config file contains no timezone:x:", style="bold red")
sys.exit()

if interactive:
entry = handle_interaction(data)
entries = handle_interaction(data)
else:
entry = name

# Check timezone existence in non-interactive mode.
if entry not in data:
console.print(
"Timezone not found in your config file.:x:", style="bold red"
)
sys.exit()
entries = [name]

# Clear file content.
file.seek(0)
file.truncate(0)

for line in data:
if not line == entry:
file.write(f"{line}\n")
for entry in entries:
# Check timezone existence in non-interactive mode.
if entry not in data:
console.print(
f"Timezone {entry} not found in your config file.:x:",
style="bold red",
)

data.remove(entry)
removed_timezones.append(
f"[bold blue]{entry}[/bold blue] :white_check_mark:"
)

line_break = "\n"
console.print(
f"[bold green]Timezone removed:[bold green] [bold blue]{entry}[/bold blue] :white_check_mark:"
f"[bold green]Timezone removed:[bold green]\n{line_break.join(removed_timezones)}"
)

if not data:
console.print(
f"\n[bold red]No timezones in config.[/bold red]\n{add_prompt}",
style="bold green",
)
sys.exit(0)

[file.write(f"{line}\n") for line in data]


def handle_interaction(data: List) -> str:
def handle_interaction(data: List, multi_select=True) -> List[str]:
"""
Display interactive menu on the terminal.
"""
selections = []
try:
terminal_menu = TerminalMenu(data)
menu_entry_index: Optional[int] = terminal_menu.show()
terminal_menu = TerminalMenu(
data, multi_select=multi_select, show_multi_select_hint=multi_select
)
menu_entry_index: Optional[Tuple] = terminal_menu.show()

# Check for None value when user presses `esc` or `ctrl + c`
if menu_entry_index is None:
raise KeyboardInterrupt

# if more than one timezone is selected.
for index in menu_entry_index:
selections.append(data[index])

except KeyboardInterrupt:
console.print("Exit:x:")
sys.exit()

return data[menu_entry_index]
return selections


def extract_fuzzy_country_data(
Expand Down Expand Up @@ -286,12 +304,15 @@ def get_local_utc_time():
)


def match_fuzzy(query):
def match_fuzzy(query) -> List[str]:
timezones = []
all_timezones = list(pytz.all_timezones)
matches = process.extractBests(query, all_timezones)

for match in matches:
if match[1] == 100:
return [match[0]]

if match[1] >= 75:
timezones.append(match[0])

Expand Down

0 comments on commit 62bd87f

Please sign in to comment.