Skip to content

Instantly share code, notes, and snippets.

@bedhabits
Forked from jbernardoviana/app.rb
Created November 23, 2019 12:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bedhabits/516f68a57a3b0069ea092e689ebbf749 to your computer and use it in GitHub Desktop.
Save bedhabits/516f68a57a3b0069ea092e689ebbf749 to your computer and use it in GitHub Desktop.
real_estate
require_relative 'router'
require_relative 'controller'
require_relative 'repository'
file_path = 'properties.csv'
repo = Repository.new(file_path)
controller = Controller.new(repo)
router = Router.new(controller)
router.run
require_relative 'view'
require_relative 'property'
require_relative 'imovirtual_service'
class Controller
def initialize(repo)
@repository = repo
@view = View.new
end
def create
name = @view.ask_for(:name)
area = @view.ask_for(:area).to_i
price = @view.ask_for(:price).to_i
property = Property.new(name: name, price: price, area: area)
@repository.add(property)
list
end
def list
properties = @repository.all
@view.display(properties)
end
def destroy
list
index = @view.ask_for(:index).to_i - 1
@repository.destroy(index)
list
end
def show
list
index = @view.ask_for(:index).to_i - 1
property = @repository.find(index)
@view.show_details(property)
end
def mark_as_sold
list
index = @view.ask_for(:index).to_i - 1
property = @repository.find(index)
property.mark_as_sold!
@repository.save
list
end
def imo_scraper
keyword = @view.ask_for("keyword")
service = ImovirtualService.new(keyword)
properties_scraped = service.call.sort_by { |el| el.price }.reverse
@view.display(properties_scraped)
index = @view.ask_for(:index).to_i - 1
property = properties_scraped[index]
@repository.add(property)
list
end
end
require 'nokogiri'
require 'open-uri'
require_relative 'property'
require 'byebug'
class ImovirtualService
def initialize(keyword)
@url = "https://www.imovirtual.com/en/comprar/#{keyword}/"
@html_file = open(@url).read
@html_doc = Nokogiri::HTML(@html_file)
@properties = []
end
def call
@html_doc.search('.offer-item-details').each do |elem|
name = elem.search(".offer-item-title").text
area = elem.search(".offer-item-area").text.strip.to_i
price = elem.search(".offer-item-price").text.strip.gsub(/\s/, "").to_i
@properties << Property.new(name: name, area: area, price: price)
end
@properties
end
end
ImovirtualService.new('apartamento').call
name area price sold
hey 500 100000 false
hey 500 100000 false
hey 500 100000 false
heeeeey 500 100000 false
T3 VARANDAS DO RIO acabamentos de luxo na Zona Ribeirinha... 130 290 false
Fórum Oeiras - Apartamento T1, Equipado e Mobilado 57 275000 false
Penthouse T5 no coração de Lisboa 250 1680000 true
class Property
attr_reader :name, :area, :price
def initialize(attr = {})
@name = attr[:name]
@area = attr[:area]
@price = attr[:price]
@sold = attr[:sold] || false
end
def to_csv
[@name, @area, @price, @sold]
end
def details
puts "Name: #{@name}"
puts "Area: #{@area}m^2"
puts "Price: #{@price}€"
puts "--"
end
def sold?
@sold
end
def mark_as_sold!
@sold = true
end
end
require 'csv'
require 'pry-byebug'
require_relative 'property'
class Repository
def initialize(csv_file_path)
@csv_file_path = csv_file_path
@properties = []
load
end
def all
@properties
end
def add(property_obj)
@properties << property_obj
save
end
def update(prop)
property = find(index)
end
def find(index)
@properties.fetch(index)
end
def destroy(index)
@properties.delete_at(index)
save
end
def save
options = { col_sep: ',', force_quotes: true, quote_char: '"' }
CSV.open(@csv_file_path, 'wb', options) do |csv|
csv << ["name", "area", "price", "sold"]
@properties.each do |prop|
csv << prop.to_csv
end
end
end
private
def load
options = { col_sep: ',', quote_char: '"', headers: :first_row, header_converters: :symbol }
CSV.foreach(@csv_file_path, options) do |row|
row[:sold] = row[:sold] == "true"
@properties << Property.new(row)
end
end
end
class Router
def initialize(controller)
@controller = controller
@running = true
end
def welcome
puts "Welcome to Our property manager"
puts "---"
end
def run
welcome
while @running
display_options
option = gets.chomp.to_i
print `clear`
route_action(option)
end
end
private
def display_options
puts ""
puts "Chose one option please!"
puts "1 - List"
puts "2 - Add"
puts "3 - Destroy"
puts "4 - Show details"
puts "5 - Imovirtual Scraper!"
puts "6 - Sell!"
puts "7 - Exit!"
end
def route_action(opt)
case opt
when 1 then @controller.list
when 2 then @controller.create
when 3 then @controller.destroy
when 4 then @controller.show
when 5 then @controller.imo_scraper
when 6 then @controller.mark_as_sold
when 7 then stop
end
end
def stop
@running = false
end
end
class View
def ask_for(action)
puts "Give me the #{action}:"
print "> "
gets.chomp
end
def display(properties)
properties.each_with_index do |elem, ix|
puts "#{ix + 1} - #{elem.sold? ? '[S]' : '[ ]'} - #{elem.name} (#{elem.price}€)"
end
end
def show_details(prop)
puts "#{prop.details}"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment