Skip to content

Commit

Permalink
feat: improve display
Browse files Browse the repository at this point in the history
  • Loading branch information
walid committed Sep 10, 2024
1 parent def3985 commit 7654896
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 43 deletions.
65 changes: 64 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ requests = "^2.32.3"
termcolor = "^2.4.0"
click = "^8.1.7"
rich = "^13.8.0"
pyhyphen = "^4.0.4"


[build-system]
Expand Down
58 changes: 16 additions & 42 deletions wikidict/main.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,37 @@
import sys
import time
import click
import requests
import itertools
import threading
import os
import textwrap
from rich.console import Console
from rich.spinner import Spinner
from rich.text import Text
from wikidict.lancodes import codes
from wikidict.utils import justify

console = Console()
BASE_URL = f"https://{lang}.wikipedia.org/w/api.php?continue=&action=query&titles={query}&prop=extracts&exintro=&explaintext=&format=json&redirects&formatversion=2"
BASE_URL = "https://{lang}.wikipedia.org/w/api.php?continue=&action=query&titles={query}&prop=extracts&exintro=&explaintext=&format=json&redirects&formatversion=2"
class Info:
SUMMARY = "Not Found"

def get_summary(query, lang):
url = BASE_URL.format(lang=lang,query=query)
try:
response = requests.get(BASE_URL).json()
response = requests.get(url).json()
pages = response['query']['pages']
except Exception as e:
print("Failed to get page")
extract = pages[0].get('extract', None)
if extract is not None:
Info.SUMMARY = extract

def justify_text(text, width):
words = text.split()
lines = []
line = []
line_length = 0
for word in words:
if line_length + len(word) + len(line) <= width:
line.append(word)
line_length += len(word)
else:
if line:
spaces_to_add = width - line_length
spaces_between_words = len(line) - 1
if spaces_between_words > 0:
space_per_gap = spaces_to_add // spaces_between_words
extra_spaces = spaces_to_add % spaces_between_words
justified_line = ''
for i, word in enumerate(line):
justified_line += word
if i < spaces_between_words:
justified_line += ' ' * (space_per_gap + (1 if i < extra_spaces else 0))
lines.append(justified_line)
else:
lines.append(line[0])
line = [word]
line_length = len(word)
if line:
lines.append(' '.join(line)) # Last line is left-aligned
return '\n'.join(lines)
def typewrite(text, delay=0.07):
"""Simulate ChatGPT-style typewriting effect."""
for char in text:
console.print(char, end='', style="bold green")
time.sleep(delay)
console.print()

@click.command()
@click.argument('query', nargs=-1)
Expand All @@ -66,26 +45,21 @@ def main(query, lang, color):
# Start a spinner thread while loading
worker = threading.Thread(target=get_summary, args=(query, lang))
worker.start()

# Create a spinner using rich
spinner = Spinner('dots', text='Fetching summary...')
with console.status(spinner, spinner_style="green") as status:
while worker.is_alive():
worker.join(0.1) # Ensure we don't hang the main thread

# Summary has been fetched
worker.join(0.1)
terminal_width = os.get_terminal_size().columns
text_width = int(0.8 * terminal_width) # 80% of terminal width
text_width = int(0.8 * terminal_width)
summary_text = Info.SUMMARY

# Justify the text
justified_summary = justify_text(summary_text, text_width)
justified_summary = justify(summary_text, text_width)

if color:
justified_summary = Text(justified_summary, style="bold green")

# Print the result with rich
console.print(justified_summary)
typewrite(justified_summary)

if __name__ == "__main__":
main()
60 changes: 60 additions & 0 deletions wikidict/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import textwrap
import hyphen
import shutil

def justify(text, width=None):
if width is None:
width = shutil.get_terminal_size().columns

# Initialize the hyphenator
h = hyphen.Hyphenator('en_US')

# Split the text into words
words = text.split()

lines = []
current_line = []
current_length = 0

for word in words:
if current_length + len(word) + len(current_line) <= width:
current_line.append(word)
current_length += len(word)
else:
if current_line:
# Justify the current line
spaces_needed = width - current_length
gaps = len(current_line) - 1
if gaps > 0:
space_per_gap = spaces_needed // gaps
extra_spaces = spaces_needed % gaps
justified_line = ''
for i, w in enumerate(current_line):
justified_line += w
if i < gaps:
justified_line += ' ' * (space_per_gap + (1 if i < extra_spaces else 0))
lines.append(justified_line)
else:
lines.append(current_line[0].ljust(width))

# Start a new line
current_line = [word]
current_length = len(word)

# Check if hyphenation is needed
while current_length > width:
hyphenated = h.wrap(current_line[-1], width - current_length + len(current_line[-1]))
if len(hyphenated) > 1:
current_line[-1] = hyphenated[0] + '-'
lines.append(' '.join(current_line).ljust(width))
current_line = [hyphenated[1]]
current_length = len(hyphenated[1])
else:
break

# Add the last line without justification
if current_line:
lines.append(' '.join(current_line))

return '\n'.join(lines)

0 comments on commit 7654896

Please sign in to comment.