This repository has been archived by the owner on Oct 26, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
app.rb
108 lines (91 loc) · 2.34 KB
/
app.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
require 'rubygems'
require 'sinatra'
require 'sinatra/reloader' if development?
require 'sequel'
require 'json'
require 'open-uri'
require 'nokogiri'
# Connect to database.
db_url = ENV['DATABASE_URL']
if db_url
# If a database URL is passed (e.g. on Heroku), connect to that database.
Sequel.connect db_url
else
# Use in-memory database.
db = Sequel.sqlite
# And create database schema for development.
db.create_table :to_watches do
primary_key :id
text :comment
text :link, :null => false
text :title
TrueClass :watched, :default => false
end
end
# Prevent Model::update from raising exceptions when trying to update a
# restricted field (like an id). Useful when updating things from JSON.
Sequel::Model.strict_param_setting = false
class ToWatch < Sequel::Model
plugin :json_serializer, :naked => true
def link= new_link
self.title = get_title_for_link new_link if new_link != self.link
super new_link
end
end
set :default_encoding => "utf-8"
get '/' do
erb :app, :locals => {
:to_watch_list => ToWatch.all
}
end
get '/js/app.js' do
coffee :app
end
get '/css/app.css' do
sass :app
end
# REST methods for ToWatch resource.
post '/towatch', :provides => :json do
req = request.body.read
json = JSON.parse req
tw = ToWatch.create json
return 400, tw.errors.to_hash.to_json unless tw.valid?
tw.to_json
end
get '/towatch/:id', :provides => :json do
id = params[:id].to_i
tw = ToWatch[id]
return 404 if tw.nil?
tw.to_json
end
put '/towatch/:id', :provides => :json do
id = params[:id].to_i
tw = ToWatch[id]
text = request.body.read
json = JSON.parse text
return 404 if tw.nil?
tw.update json
return 400, tw.errors.to_hash.to_json unless tw.valid?
tw.to_json
end
delete '/towatch/:id' do
id = params[:id].to_i
tw = ToWatch[id]
return 404 if tw.nil?
tw.destroy
200
end
# Return a convenient title for a link.
def get_title_for_link link
begin
doc = Nokogiri::HTML open(link)
node = doc.search('h1').first || doc.search('title').first
node.xpath('.//text()').to_s.strip
rescue
# If something goes wrong (e.g. "link" is not a valid URL and "open"
# complained, or the resource is not HTML and Nokogiri shat the bed, or
# the HTML had no 'h1' not 'title' tags, so "node" was nil, etc), use the
# link as a title :)
link
end
end