Building the History Cube: Part One Ruby Terminal App
Introduction
Combining my passion for coding, 3D printing, and hardware, the History Cube project emerged as a fusion of digital and tangible creation. This project seeks to create a compact device delivering history facts through a terminal app. Join me on this journey as we delve into the coding, configurations of the Raspberry Pi Zero, and crafting a 3D-printed casing. For this part of the series I’m going to write the console app where users will select the history topic and facts will be displayed.
Prerequisites
Ruby Version 3.0: The terminal app is built using Ruby, and having version 3.0 installed is crucial for compatibility.
Git: To clone the project and make any changes.
Basic Understanding of the Terminal: Familiarity with basic terminal commands will empower you to navigate the project.
Writing the Ruby Terminal App
Creating the Main Menu
The main menu, coded in Ruby, uses the tty-prompt gem to make the selection of the topic simple. This will make user input easy to manage when we hook up the raspberry pi zero and 3D print it’s components.
def initialize(menu_selections)
@menu_selections = menu_selections
@facts = []
@selected_index = nil
@favorite_history = ""
end
def display_menu
system('clear') || system('cls') # Clear the console screen
prompt = TTY::Prompt.new
@favorite_history = prompt.select("Choose your favorite history subject:", @menu_selections)
end
Fetching History Facts
The app taps into the API Ninjas history events API, dynamically fetching historical facts based on user selections. We created an API helper class to fetch the data:
require'net/http'
require'json'
require'yaml'
class Api
def initialize(text)
config = YAML.load_file('config.yml')
@text = text
@url ="https://api.api-ninjas.com/v1/historicalevents?text="
@api_key = config['api_key']
end
def get_history
full_url ="#{@url}#{@text}"
headers = {
'Content-Type'=>'application/json',
'X-Api-Key'=>@api_key
}
url = URI.parse(full_url)
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = (url.scheme =='https')
request = Net::HTTP::Get.new(url, headers)
response = http.request(request)
if response.is_a?(Net::HTTPSuccess)
data =JSON.parse(response.body)
data
else
puts"HTTP request failed: #{response.code} - #{response.message}"
end
end
end
Displaying Information
Formatted information is presented on the terminal screen using the terminal-table gem. This is back in the main ConsoleApp class where the engine is run:
def call_api
api =Api.new(@favorite_history)
@facts= api.get_history[0..2]
end
def display_facts
index =0
loop do
system('clear') || system('cls')
event = @facts[index]
rows =[]
rows <<["#{event['month']}-#{event['day']}-#{event['year']}","#{Helper.wrap_word(event['event'],40)}"]
table =Terminal::Table.new(:title=>"History Facts",:headings=>['Date','Event'],:rows=> rows)
puts table
sleep 10
index +=1
break if index >= @facts.length
end
end
def run
loop do
display_menu
call_api
display_facts
end
end
end
# Example usage
menu_selections = ["Roman Empire","World War II","Revolutionary War"]
app = ConsoleApp.new(menu_selections)
app.run
Conclusion
The full code can be found on the history_cube repository. I’ll be making changes as the project continues to take shape but this is the start: https://github.com/mawittenauer/history_cube