I made a command line Hacker News reader in Ruby that pulls the latest 10 stories from HN and allows the user to cycle through them or open them with Launchy. This was to play around with Ruby and APIs.
The data that I pulled from HN was messy, like an array of hashes with arrays and hashes inside. I feel like my code is messy, and I am unsure of how it can be made cleaner.
Any advice? I'm still a begninner.
news.rb --
class News
def initialize title, url, author
@title = title
@url = url
@author = author
end
# Format display of each story.
def to_s
"\n\tTitle: #{@title}\n
\tAuthor: #{@author}\n
\tUrl: #{@url}\n\n"
end
# Insert current object's url into a variable accessible by Launchy
def get_url
@url
end
end
# Show the news story, and ask if user wants open link or move on.
def show_story
puts @stories[@counter]
@link = @stories[@counter].get_url
puts "To view this story in your browser, type OPEN\n
To see the next story, type NEXT"
@start = gets.chomp.downcase
shuffle
end
# Determine if user wants to open link or move on.
def shuffle
if @start == "open"
Launchy.open(@link)
next_story
elsif @start == "next"
@counter += 1
show_story
else
puts "Sorry, you didn't type a correct command.\n
To view this story in your browser, type OPEN\n
To see the next story, type NEXT"
@start = gets.chomp.downcase
shuffle
end
end
# After opening link, ask if user still wants to see next story
def next_story
puts "Would you still like to see the next story? Type NEXT"
@start = gets.chomp.downcase
shuffle
end
runner.rb --
require 'json'
require 'rest-client'
require 'launchy'
require_relative 'news.rb'
# Pull the latest/top 10 stories from Hacker News
data = RestClient.get('http://api.thriftdb.com/api.hnsearch.com/items/_search?limit=10&sortby=product(points,pow(2,div(div(ms(create_ts,NOW),3600000),72)))%20desc&pretty_print=true')
# Parse using JSON
parsed = JSON.parse data
# Take out the everything not under "Results" key
results = parsed.reject { |key, value| key != "results"}
# Create array and slap the value of "Results" into it
pull_items = []
pull_items = results["results"].each do |items|
pull_items << items
end
# Create an array and make each "Item" into its own item
pull_info = []
pull_items.each do |x|
pull_info << x["item"]
end
# Create a new object for each news story
@stories = pull_info.map do |s|
News.new s["title"], s["url"], s["username"]
end
# Logo and Welcome Message
puts <<STRING
_ _ _ _ _
| | | | | | | \\ | |
| |_| | __ _ ___| | _____ _ __ | \\| | _____ _____
| _ |/ _` |/ __| |/ / _ | '__| | . ` |/ _ \\ \\ /\\ / / __|
| | | | (_| | (__| | __| | | |\\ | __/\\ V V /\\__ \
\\_| |_/\\__,_|\\___|_|\\_\\___|_| \\_| \\_/\\___| \\_/\\_/ |___/
Welcome to Hacker News... from the Command Line!
STRING
# View the first story
puts "\nTo see the latest post, press any key"
start = gets
@counter = 0
show_story