107 lines
2.8 KiB
Ruby
107 lines
2.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'roda'
|
|
require 'securerandom'
|
|
require 'json'
|
|
require 'sequel'
|
|
require 'open-uri'
|
|
|
|
# URL Shortener App class
|
|
class App < Roda
|
|
plugin :sessions, secret: ENV.delete('APP_SESSION_SECRET')
|
|
plugin :render, escape: true
|
|
plugin :flash
|
|
plugin :json_parser
|
|
plugin :request_headers
|
|
|
|
DB = Sequel.sqlite("db/#{ENV.fetch('DB_NAME', nil)}")
|
|
links = DB[:links]
|
|
|
|
route do |r|
|
|
r.root do
|
|
@message = flash['message'] || 'Enter a URL'
|
|
view :home
|
|
end
|
|
|
|
r.get String do |url_code|
|
|
link = links.filter(code: url_code)
|
|
r.redirect link.first[:url] unless link.first.nil?
|
|
@message = "Link #{url_code} doesn't exist"
|
|
response.status = 404
|
|
view :home
|
|
end
|
|
|
|
r.post 'create' do
|
|
url = r.params['url']
|
|
if url.nil? || url.empty?
|
|
flash['message'] = 'Please enter a valid URL'
|
|
r.redirect '/'
|
|
end
|
|
|
|
begin
|
|
OpenURI.open_uri(url)
|
|
rescue URI::BadURIError
|
|
flash['message'] = 'Invalid URL'
|
|
r.redirect '/'
|
|
rescue OpenURI::HTTPError
|
|
flash['message'] = 'URL not found'
|
|
r.redirect '/'
|
|
rescue SocketError
|
|
flash['message'] = 'URL does not resolve'
|
|
r.redirect '/'
|
|
end
|
|
|
|
if links.filter(url:).first.nil?
|
|
code = SecureRandom.urlsafe_base64 4
|
|
links.insert(url:, code:)
|
|
@message = 'Link created'
|
|
end
|
|
code = links.filter(url:).first[:code]
|
|
@message ||= 'Link exists'
|
|
@new_link = "http://#{request.env['HTTP_HOST']}/#{code}"
|
|
view :create
|
|
end
|
|
r.on 'links' do
|
|
r.post do
|
|
if r.headers['CONTENT_TYPE'] != 'application/json'
|
|
response.status = 400
|
|
return { message: 'not a valid json request' }.to_json
|
|
end
|
|
|
|
url = r.params['url']
|
|
if url.nil?
|
|
response.status = 400
|
|
return { message: 'missing url parameter' }.to_json
|
|
end
|
|
|
|
if url.empty?
|
|
response.status = 400
|
|
return { message: 'invalid url parameter' }.to_json
|
|
end
|
|
|
|
begin
|
|
OpenURI.open_uri(url)
|
|
rescue URI::BadURIError
|
|
response.status = 400
|
|
return { message: 'invalid url parameter' }.to_json
|
|
rescue OpenURI::HTTPError
|
|
response.status = 400
|
|
return { message: 'url not found' }.to_json
|
|
rescue SocketError
|
|
response.status = 400
|
|
return { message: 'url does not resolve' }.to_json
|
|
end
|
|
|
|
if links.filter(url:).first.nil?
|
|
code = SecureRandom.urlsafe_base64 4
|
|
links.insert(url:, code:)
|
|
end
|
|
|
|
code = links.filter(url:).first[:code]
|
|
@new_link = "http://#{request.env['HTTP_HOST']}/#{code}"
|
|
return { url:, code:, link: @new_link }.to_json
|
|
end
|
|
end
|
|
end
|
|
end
|