libertree-model 0.9.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/libertree/compat.rb +29 -0
- data/lib/libertree/console.rb +17 -0
- data/lib/libertree/db.rb +37 -0
- data/lib/libertree/embedder.rb +69 -0
- data/lib/libertree/embedding/custom-providers.rb +148 -0
- data/lib/libertree/model/account-settings.rb +14 -0
- data/lib/libertree/model/account.rb +487 -0
- data/lib/libertree/model/chat-message.rb +75 -0
- data/lib/libertree/model/comment-like.rb +68 -0
- data/lib/libertree/model/comment.rb +164 -0
- data/lib/libertree/model/contact-list.rb +81 -0
- data/lib/libertree/model/embed-cache.rb +6 -0
- data/lib/libertree/model/file.rb +6 -0
- data/lib/libertree/model/forest.rb +82 -0
- data/lib/libertree/model/group-member.rb +13 -0
- data/lib/libertree/model/group.rb +47 -0
- data/lib/libertree/model/has-display-text.rb +34 -0
- data/lib/libertree/model/has-searchable-text.rb +19 -0
- data/lib/libertree/model/ignored-member.rb +13 -0
- data/lib/libertree/model/invitation.rb +6 -0
- data/lib/libertree/model/is-remote-or-local.rb +30 -0
- data/lib/libertree/model/job.rb +93 -0
- data/lib/libertree/model/member.rb +222 -0
- data/lib/libertree/model/message.rb +154 -0
- data/lib/libertree/model/node.rb +22 -0
- data/lib/libertree/model/node_affiliation.rb +14 -0
- data/lib/libertree/model/node_subscription.rb +23 -0
- data/lib/libertree/model/notification.rb +71 -0
- data/lib/libertree/model/pool-post.rb +17 -0
- data/lib/libertree/model/pool.rb +172 -0
- data/lib/libertree/model/post-hidden.rb +21 -0
- data/lib/libertree/model/post-like.rb +72 -0
- data/lib/libertree/model/post-revision.rb +9 -0
- data/lib/libertree/model/post.rb +735 -0
- data/lib/libertree/model/profile.rb +25 -0
- data/lib/libertree/model/remote-storage-connection.rb +6 -0
- data/lib/libertree/model/river.rb +249 -0
- data/lib/libertree/model/server.rb +35 -0
- data/lib/libertree/model/session-account.rb +10 -0
- data/lib/libertree/model/url-expansion.rb +6 -0
- data/lib/libertree/model.rb +48 -0
- data/lib/libertree/query.rb +167 -0
- data/lib/libertree/render.rb +28 -0
- metadata +198 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9a84aeab884f0cc3db24026c3b4063a2a7ce7ece
|
4
|
+
data.tar.gz: f29e7defa9f0dc6cc60885bc4ee213bd737f65f2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4bfa2f35c02ee6f76aa8701ed525593fcd18433f19fd9bfa2dcd21bde958f84b35f0716ff91e2c38b79d48d2331c4150bcd65ac49c7dafae275835382189c46c
|
7
|
+
data.tar.gz: ac2e3ab424a0d6daee34cfd9c0db9cab87c77c7d42b9be887211306f54379b7592ddbef9b3be77aa5a5ea679bca37079b97a4140fbcbc54b6c5bdf9347f71bdb
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Sequel
|
2
|
+
module Plugins
|
3
|
+
module Compat
|
4
|
+
module ClassMethods
|
5
|
+
def s(*args)
|
6
|
+
Sequel::Model.db[*args].map {|row| self.new(row)}
|
7
|
+
end
|
8
|
+
|
9
|
+
def s_wrap(*args)
|
10
|
+
Sequel::Model.db[*args].map {|row| self.send(:wrap_dataset, row)}
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
# Creates a model object and augments it with methods for
|
15
|
+
# otherwise undefined values. There are no setters for those
|
16
|
+
# keys that are no valid column identifiers.
|
17
|
+
def wrap_dataset(values)
|
18
|
+
undefined = values.keys - self.columns
|
19
|
+
object = self.new values.reject{|key| undefined.include? key}
|
20
|
+
klass = class << object; self; end
|
21
|
+
undefined.each do |method_name|
|
22
|
+
klass.send(:define_method, method_name) { values[method_name] }
|
23
|
+
end
|
24
|
+
object
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'libertree/db'
|
2
|
+
require 'irb'
|
3
|
+
|
4
|
+
module Libertree
|
5
|
+
module Console
|
6
|
+
def self.init(db_conf_path='database.yaml')
|
7
|
+
Libertree::DB.load_config db_conf_path
|
8
|
+
Libertree::DB.dbh # connect
|
9
|
+
require 'libertree/model'
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.start
|
13
|
+
puts "\n== Libertree console ==\n\n"
|
14
|
+
IRB.start
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/libertree/db.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'sequel'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Libertree
|
5
|
+
module DB
|
6
|
+
LAST_MIGRATION = "2014-08-31-2050-search-indices.sql"
|
7
|
+
|
8
|
+
def self.config
|
9
|
+
@config
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.config=(hash)
|
13
|
+
@config = hash
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.load_config(filename)
|
17
|
+
config_file = filename
|
18
|
+
configs ||= YAML.load( IO.read(config_file) )
|
19
|
+
env = ENV['LIBERTREE_ENV'] || 'development'
|
20
|
+
@config = configs[env]
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.dbh
|
24
|
+
@dbh ||= Sequel.postgres(host: config['host'],
|
25
|
+
database: config['database'],
|
26
|
+
user: config['username'],
|
27
|
+
password: config['password'],
|
28
|
+
max_connections: 8)
|
29
|
+
|
30
|
+
# ensure the latest required migration exists
|
31
|
+
if @dbh[:schema_migrations].where(filename: LAST_MIGRATION).count == 0
|
32
|
+
fail "Libertree::DB: migration `#{LAST_MIGRATION}' not found. Please update libertree-db."
|
33
|
+
end
|
34
|
+
@dbh
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'oembed'
|
2
|
+
require_relative 'embedding/custom-providers'
|
3
|
+
|
4
|
+
module Libertree
|
5
|
+
module Embedder
|
6
|
+
OEmbed::Providers.register(
|
7
|
+
OEmbed::Providers::Youtube,
|
8
|
+
OEmbed::Providers::Vimeo,
|
9
|
+
OEmbed::Providers::Flickr,
|
10
|
+
OEmbed::Providers::SoundCloud
|
11
|
+
)
|
12
|
+
|
13
|
+
# Ask Youtube to return HTTPS embed codes to keep their iframes
|
14
|
+
# from ending up empty when the page is served over HTTPS
|
15
|
+
OEmbed::Providers::Youtube.endpoint += "?scheme=https"
|
16
|
+
|
17
|
+
def self.get(url)
|
18
|
+
Libertree::Embedding::CustomProviders.get(url) || OEmbed::Providers.get(url, {width: 500}).html
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.autoembed(text)
|
22
|
+
urls = extract_urls(text)
|
23
|
+
urls.each do |url|
|
24
|
+
cached = Libertree::Model::EmbedCache[ url: url ]
|
25
|
+
next if cached
|
26
|
+
|
27
|
+
Libertree::Model::Job.find_or_create(
|
28
|
+
task: 'http:embed',
|
29
|
+
params: {
|
30
|
+
'url' => url
|
31
|
+
}.to_json
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# @param [Nokogiri::HTML::DocumentFragment] parsed HTML tree
|
37
|
+
def self.inject_objects(html)
|
38
|
+
# extract every URL from a paragraph and append embed object if supported
|
39
|
+
html.css('p').each do |p|
|
40
|
+
# collect urls, ignore relative links
|
41
|
+
urls = p.xpath(".//a[not(starts-with(@href,'/'))]/@href").map(&:value).reverse
|
42
|
+
urls.each do |url|
|
43
|
+
cached = Libertree::Model::EmbedCache.
|
44
|
+
s("SELECT * FROM embed_cache WHERE url IN (?,?)", url, url.gsub('&', '&'))
|
45
|
+
|
46
|
+
if cached[0]
|
47
|
+
p.add_next_sibling("<div class='embed'>#{cached[0][:object]}</div>")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
html
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.supported
|
55
|
+
@supported ||= Regexp.union(
|
56
|
+
OEmbed::Providers.urls.keys.concat Libertree::Embedding::CustomProviders.urls.keys
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.extract_urls(text)
|
61
|
+
Render.to_html_nodeset(text).
|
62
|
+
xpath('.//a/@href').
|
63
|
+
map {|href| href.value.strip}.
|
64
|
+
uniq.
|
65
|
+
find_all {|href| href =~ self.supported }
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module Libertree
|
4
|
+
module Embedding
|
5
|
+
class Error < StandardError; end
|
6
|
+
|
7
|
+
module CustomProviders
|
8
|
+
def self.urls
|
9
|
+
{
|
10
|
+
Youku.format => Youku,
|
11
|
+
FreeMusicArchive.format => FreeMusicArchive,
|
12
|
+
Jamendo.format => Jamendo,
|
13
|
+
TED.format => TED,
|
14
|
+
Bandcamp.format => Bandcamp,
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.get(url)
|
19
|
+
self.urls.each do |k,v|
|
20
|
+
if url =~ k
|
21
|
+
return v.get(url)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
class Youku
|
28
|
+
def self.format
|
29
|
+
%r{http://v\.youku.com/v_show/id_(.+)\.html}
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.get(url)
|
33
|
+
m = url.match self.format
|
34
|
+
if m
|
35
|
+
return <<OBJECT
|
36
|
+
<embed src="http://player.youku.com/player.php/sid/#{m[1]}/v.swf" allowFullScreen="true" quality="high" width="480" height="400" align="middle" allowScriptAccess="always" type="application/x-shockwave-flash"></embed>
|
37
|
+
OBJECT
|
38
|
+
else
|
39
|
+
raise Libertree::Embedding::Error, "failed to extract video id"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class FreeMusicArchive
|
45
|
+
def self.format
|
46
|
+
%r{http://freemusicarchive\.org/music/.+}
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.get(url)
|
50
|
+
return unless url =~ self.format
|
51
|
+
|
52
|
+
uri = URI.parse(url)
|
53
|
+
Timeout.timeout(10) do
|
54
|
+
Net::HTTP.start(uri.host) do |http|
|
55
|
+
resp = http.get(uri.path)
|
56
|
+
html = Nokogiri::HTML(resp.body)
|
57
|
+
e = html.css('.inp-embed-code input')[0]
|
58
|
+
if e
|
59
|
+
return e.attr('value')
|
60
|
+
else
|
61
|
+
raise Libertree::Embedding::Error, "failed to find embedding code"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Jamendo
|
69
|
+
def self.format
|
70
|
+
%r{http://www.jamendo\.com/.+/track/.+}
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.get(url)
|
74
|
+
return unless url =~ self.format
|
75
|
+
|
76
|
+
uri = URI.parse(url)
|
77
|
+
Timeout.timeout(10) do
|
78
|
+
Net::HTTP.start(uri.host) do |http|
|
79
|
+
resp = http.get(uri.path)
|
80
|
+
html = Nokogiri::HTML(resp.body)
|
81
|
+
e = html.css('.preview object')[0]
|
82
|
+
if e
|
83
|
+
return e.to_html
|
84
|
+
else
|
85
|
+
raise Libertree::Embedding::Error, "failed to find embedding code"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class TED
|
93
|
+
def self.format
|
94
|
+
%r{http://www\.ted\.com/talks/.+\.html}
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.get(url)
|
98
|
+
return unless url =~ self.format
|
99
|
+
|
100
|
+
uri = URI.parse(url)
|
101
|
+
Timeout.timeout(10) do
|
102
|
+
Net::HTTP.start(uri.host) do |http|
|
103
|
+
resp = http.get(uri.path)
|
104
|
+
html = Nokogiri::HTML(resp.body)
|
105
|
+
e = html.css('#embedthisvideo')[0]
|
106
|
+
if e
|
107
|
+
return e.attr('value')
|
108
|
+
else
|
109
|
+
raise Libertree::Embedding::Error, "failed to find embedding code"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
class Bandcamp
|
117
|
+
def self.format
|
118
|
+
%r{https?://.*\.bandcamp\.com/(track|album)/.+}
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.get(url)
|
122
|
+
return unless url =~ self.format
|
123
|
+
|
124
|
+
type = $1
|
125
|
+
|
126
|
+
uri = URI.parse(url)
|
127
|
+
Timeout.timeout(10) do
|
128
|
+
Net::HTTP.start(uri.host) do |http|
|
129
|
+
resp = http.get(uri.path)
|
130
|
+
html = Nokogiri::HTML(resp.body)
|
131
|
+
node = html.xpath("//meta[@property='og:video']/@content")
|
132
|
+
if node.empty?
|
133
|
+
raise Libertree::Embedding::Error, "failed to find embedding code"
|
134
|
+
else
|
135
|
+
if node.text.match(/#{type}=(\d+)/)
|
136
|
+
"<iframe width=\"400\" height=\"100\" frameborder=\"0\" allowtransparency=\"true\" src=\"https://bandcamp.com/EmbeddedPlayer/size=venti/#{type}=#{$1}\"></iframe>"
|
137
|
+
else
|
138
|
+
raise Libertree::Embedding::Error, "failed to find #{type} id"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|