content-preview 0.0.1 → 0.1.1
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.
- data/Gemfile +2 -0
- data/Gemfile.lock +1 -1
- data/Procfile +1 -0
- data/bin/cp-server +8 -19
- data/content-preview.gemspec +3 -3
- data/lib/content-preview/parser.rb +12 -7
- data/lib/content-preview/router.rb +4 -2
- data/lib/content-preview/version.rb +1 -1
- data/spec/parser/parser_spec.rb +8 -1
- metadata +6 -8
- data/config.ru +0 -23
- data/lib/content-preview/router/router.rb +0 -25
- data/roadmap.txt +0 -90
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/Procfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
web: bundle exec rackup config.ru -p $PORT
|
data/bin/cp-server
CHANGED
@@ -1,29 +1,22 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'thor'
|
4
|
-
require 'json'
|
5
|
-
require 'rack'
|
6
|
-
require 'yaml'
|
7
|
-
|
8
|
-
require 'content-preview/router'
|
9
|
-
require 'content-preview'
|
10
|
-
|
11
4
|
require 'rack'
|
12
5
|
require 'rack/cors'
|
6
|
+
require 'content-preview/router'
|
13
7
|
|
14
8
|
class ContentPreviewServer < Thor
|
15
9
|
|
16
|
-
desc "
|
10
|
+
desc "init", "Starts a Rack server with the Rack::Handler and Port given as argument Defaults are Webrick and"
|
11
|
+
|
17
12
|
method_option :server, aliases: '-s', default: 'WEBrick', desc: "The Rack::Handler server to use (Webrick, Mongrel, Thin ...)"
|
18
13
|
method_option :port, aliases: '-p', default: '3210', desc: "The port to run the server on"
|
19
14
|
method_option :origin, aliases: '-o', default: '*', desc: "Allowed client origins"
|
20
|
-
def start
|
21
|
-
origin, port, server = options[:origin], options[:port], options[:server]
|
22
15
|
|
23
|
-
|
16
|
+
def init
|
17
|
+
origin, port, server = options[:origin], options[:port], options[:server]
|
18
|
+
service = Rack::Builder.new do
|
24
19
|
use Rack::CommonLogger
|
25
|
-
use Rack::ShowExceptions
|
26
|
-
use Rack::Lint
|
27
20
|
|
28
21
|
use Rack::Cors do
|
29
22
|
allow do
|
@@ -34,13 +27,9 @@ class ContentPreviewServer < Thor
|
|
34
27
|
end
|
35
28
|
end
|
36
29
|
|
37
|
-
puts "Launch handler #{ server } on port #{ port }"
|
38
30
|
run ContentPreview::Router::Base
|
39
|
-
|
40
31
|
end
|
41
32
|
|
42
|
-
Rack::Handler.const_get(server).run(
|
33
|
+
Rack::Handler.const_get(server).run(service, Host: '0.0.0.0', Port: port)
|
43
34
|
end
|
44
|
-
end
|
45
|
-
|
46
|
-
ContentPreviewServer.start
|
35
|
+
end
|
data/content-preview.gemspec
CHANGED
@@ -13,11 +13,11 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.summary = "A simple service for getting URL page informations"
|
14
14
|
s.description = "A simple service for getting URL page informations"
|
15
15
|
|
16
|
-
s.files =
|
16
|
+
s.files = [".gitignore", ".rspec", "Gemfile", "Gemfile.lock", "MIT-LICENSE", "Procfile", "README.md", "Rakefile", "bin/cp-server", "content-preview.gemspec", "js/src/content-preview.coffee", "lib/content-preview.rb", "lib/content-preview/parser.rb", "lib/content-preview/router.rb", "lib/content-preview/router/handlers/default.rb", "lib/content-preview/router/routes.yml", "lib/content-preview/version.rb", "lib/tasks/content-preview_tasks.rake", "spec/parser/parser_spec.rb", "spec/spec_helper.rb"]
|
17
17
|
s.require_paths = ["lib"]
|
18
|
-
s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
18
|
+
# s.test_files = `git ls-files -- {spec}/*`.split("\n")
|
19
19
|
s.bindir = "bin"
|
20
|
-
s.executables = 'cp-server'
|
20
|
+
s.executables = ['cp-server']
|
21
21
|
|
22
22
|
s.add_dependency 'thor'
|
23
23
|
s.add_dependency 'nokogiri'
|
@@ -3,7 +3,7 @@ require 'nokogiri'
|
|
3
3
|
|
4
4
|
module ContentPreview
|
5
5
|
class Parser
|
6
|
-
attr_accessor :title, :description, :images
|
6
|
+
attr_accessor :title, :description, :images, :video
|
7
7
|
|
8
8
|
def initialize(images = [])
|
9
9
|
self.images = images
|
@@ -13,16 +13,17 @@ module ContentPreview
|
|
13
13
|
return unless url =~ /^http\:\/\//
|
14
14
|
|
15
15
|
begin
|
16
|
-
result = {}
|
17
16
|
document = Nokogiri::HTML(open(url))
|
18
17
|
process_open_graph(document)
|
19
18
|
process_meta_data(document, url)
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
# Return computed data
|
21
|
+
{
|
22
|
+
'title' => self.title,
|
23
|
+
'description' => self.description,
|
24
|
+
'images' => self.images,
|
25
|
+
'video' => self.video
|
26
|
+
}
|
26
27
|
rescue Exception => e
|
27
28
|
nil
|
28
29
|
end
|
@@ -40,6 +41,10 @@ module ContentPreview
|
|
40
41
|
|
41
42
|
when 'og:image'
|
42
43
|
self.images << tag['content']
|
44
|
+
|
45
|
+
when 'og:video'
|
46
|
+
self.video = tag['content']
|
47
|
+
|
43
48
|
end
|
44
49
|
end
|
45
50
|
end
|
@@ -1,3 +1,7 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
require 'content-preview'
|
1
5
|
require 'content-preview/router/handlers/default'
|
2
6
|
|
3
7
|
module ContentPreview
|
@@ -15,8 +19,6 @@ module ContentPreview
|
|
15
19
|
path = '/' if path.empty?
|
16
20
|
end
|
17
21
|
|
18
|
-
# require File.dirname(__FILE__) + '/' + @routes[path]
|
19
|
-
|
20
22
|
class_name = @routes[path].capitalize
|
21
23
|
Handlers.const_get(class_name).call env
|
22
24
|
end
|
data/spec/parser/parser_spec.rb
CHANGED
@@ -56,10 +56,17 @@ describe ContentPreview::Parser, '::process' do
|
|
56
56
|
preview = @content_preview.process "http://www.youtube.com/watch?v=OK7pfLlsUQM"
|
57
57
|
preview.should_not be_nil
|
58
58
|
preview.should include(
|
59
|
-
{
|
59
|
+
{
|
60
|
+
"title"=>"The Artist - Official Trailer [HD]",
|
61
|
+
"description"=>"Subscribe http://ow.ly/3UVvY | Facebook http://ow.ly/3UVxn | Twitter http://ow.ly/3UVyA Release Date: 23 November 2011 Genre: Romance | Comedy | Drama Cast: ...",
|
62
|
+
"images"=>["http://i4.ytimg.com/vi/OK7pfLlsUQM/mqdefault.jpg"],
|
63
|
+
"video" => "http://www.youtube.com/v/OK7pfLlsUQM?version=3&autohide=1"
|
64
|
+
}
|
60
65
|
)
|
61
66
|
|
62
67
|
@content_preview.title.should_not be_nil
|
63
68
|
@content_preview.images.should_not be_empty
|
69
|
+
@content_preview.video.should_not be_nil
|
64
70
|
end
|
71
|
+
|
65
72
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: content-preview
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: thor
|
@@ -120,21 +120,19 @@ files:
|
|
120
120
|
- Gemfile
|
121
121
|
- Gemfile.lock
|
122
122
|
- MIT-LICENSE
|
123
|
+
- Procfile
|
123
124
|
- README.md
|
124
125
|
- Rakefile
|
125
126
|
- bin/cp-server
|
126
|
-
- config.ru
|
127
127
|
- content-preview.gemspec
|
128
128
|
- js/src/content-preview.coffee
|
129
129
|
- lib/content-preview.rb
|
130
130
|
- lib/content-preview/parser.rb
|
131
131
|
- lib/content-preview/router.rb
|
132
132
|
- lib/content-preview/router/handlers/default.rb
|
133
|
-
- lib/content-preview/router/router.rb
|
134
133
|
- lib/content-preview/router/routes.yml
|
135
134
|
- lib/content-preview/version.rb
|
136
135
|
- lib/tasks/content-preview_tasks.rake
|
137
|
-
- roadmap.txt
|
138
136
|
- spec/parser/parser_spec.rb
|
139
137
|
- spec/spec_helper.rb
|
140
138
|
homepage: http://glyph.fr
|
@@ -151,7 +149,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
151
149
|
version: '0'
|
152
150
|
segments:
|
153
151
|
- 0
|
154
|
-
hash:
|
152
|
+
hash: -3903559105997768296
|
155
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
156
154
|
none: false
|
157
155
|
requirements:
|
@@ -160,10 +158,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
158
|
version: '0'
|
161
159
|
segments:
|
162
160
|
- 0
|
163
|
-
hash:
|
161
|
+
hash: -3903559105997768296
|
164
162
|
requirements: []
|
165
163
|
rubyforge_project:
|
166
|
-
rubygems_version: 1.8.
|
164
|
+
rubygems_version: 1.8.24
|
167
165
|
signing_key:
|
168
166
|
specification_version: 3
|
169
167
|
summary: A simple service for getting URL page informations
|
data/config.ru
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'rack'
|
3
|
-
require 'yaml'
|
4
|
-
require 'rack/cors'
|
5
|
-
|
6
|
-
require 'content-preview/router'
|
7
|
-
require 'content-preview'
|
8
|
-
|
9
|
-
use ::Rack::CommonLogger
|
10
|
-
# use ::Rack::ShowExceptions
|
11
|
-
use ::Rack::Lint
|
12
|
-
#use Rack::Static, :urls => ["/static"]
|
13
|
-
|
14
|
-
use Rack::Cors do
|
15
|
-
allow do
|
16
|
-
origins 'http://localhost:3000'
|
17
|
-
resource %r{/},
|
18
|
-
:headers => ['Origin', 'Accept', 'Content-Type'],
|
19
|
-
:methods => [:get, :post]
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
run ContentPreview::Router::Base.new
|
@@ -1,25 +0,0 @@
|
|
1
|
-
require 'content-preview/server/handlers/default'
|
2
|
-
|
3
|
-
module ContentPreview
|
4
|
-
module Router
|
5
|
-
class Base
|
6
|
-
def initialize(path = File.expand_path('../routes.yml', __FILE__))
|
7
|
-
@routes = YAML.load_file path
|
8
|
-
end
|
9
|
-
|
10
|
-
def call(env)
|
11
|
-
path = env['PATH_INFO']
|
12
|
-
|
13
|
-
until @routes.has_key? path do
|
14
|
-
path = path.rpartition('/').first
|
15
|
-
path = '/' if path.empty?
|
16
|
-
end
|
17
|
-
|
18
|
-
require File.dirname(__FILE__) + '/' + @routes[path]
|
19
|
-
|
20
|
-
class_name = @routes[path].capitalize
|
21
|
-
Handlers.const_get(class_name).call env
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/roadmap.txt
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
ROADMAP :
|
2
|
-
|
3
|
-
----------------------------------------------------------------------
|
4
|
-
|
5
|
-
V.0.1 :
|
6
|
-
|
7
|
-
Développement du parser et de différentes stratégies permettant un traitement plus approfondi et spécifique pour certaines URLS connues.
|
8
|
-
|
9
|
-
Description très basique :
|
10
|
-
|
11
|
-
1. Le parser récupère une URL en entrée
|
12
|
-
2. Le parser d'URL s'occupe de récupérer la page HTML correspondant à l'URL
|
13
|
-
3. Les headers checkés en priorité sont :
|
14
|
-
a. Les balise meta OpenGraph (og:xxx)
|
15
|
-
b. <title>, <meta description>
|
16
|
-
c. Les images contenues dans la page
|
17
|
-
4. Le parser renvoie soit une réponse vide si rien n'est trouvé et sinon un hash de type :
|
18
|
-
{
|
19
|
-
title: "Super video",
|
20
|
-
description: "Excellent one, gotta love it",
|
21
|
-
type: "video",
|
22
|
-
images: [
|
23
|
-
"http://example.com/image1.jpg",
|
24
|
-
"http://example.com/image2.jpg",
|
25
|
-
"http://example.com/image3.jpg"
|
26
|
-
]
|
27
|
-
}
|
28
|
-
|
29
|
-
----------------------------------------------------------------------
|
30
|
-
|
31
|
-
V.0.2 :
|
32
|
-
|
33
|
-
Il faut transformer le composant en service HTTP très simple, recevant des requêtes POST ayant pour unique paramètre le champ contenant le texte de l'utilisateur à parser.
|
34
|
-
|
35
|
-
1. Le service reçoit une réponse POST contenant un champ "content" contenant le texte à parser
|
36
|
-
2. Il appelle ContentPreview#parse avec le champ "content" comme argument afin de déléguer la tâche au parser
|
37
|
-
3. Selon la réponse successful ou non du parser, un code HTTP différent est renvoyé ainsi que le résultat du parsing ou non :
|
38
|
-
a. Le parser renvoie une réponse vide (nil, s'évaluant à false), indiquant que rien n'a été trouvé, le service renvoie un code 404
|
39
|
-
b. Le parser renvoie un hash (s'évaluant à true), celui-ci est converti en JSON et renvoyé avec un code 200
|
40
|
-
|
41
|
-
|
42
|
-
----------------------------------------------------------------------
|
43
|
-
|
44
|
-
V.0.3 :
|
45
|
-
|
46
|
-
Développer un client JS (dépendant de jQuery) permettant de parser un contenu texte et/ou HTML, d'interroger le serveur sur d'éventuels contenus media et d'appeler un callback défini par l'utisateur si un contenu media est renvoyé.
|
47
|
-
Il s'accompagnera d'un plugin jQuery permettant l'utilisation de $.fn.data() afin de persister l'état de la preview et ne la rafraîchir qu'en cas de besoin.
|
48
|
-
|
49
|
-
Quelques spécifications :
|
50
|
-
|
51
|
-
1. La méthode #parse est appelée sur le client et prend en argument :
|
52
|
-
a. une chaîne de caractères pouvant contenir du HTML
|
53
|
-
b. une fonction callback recevant comme unique argument un objet JS de type :
|
54
|
-
{
|
55
|
-
title: "xx",
|
56
|
-
description: "xxxxx",
|
57
|
-
image: "http://example.com/pic.jpg"
|
58
|
-
}
|
59
|
-
2. La méthode parse du client s'occupe de récupérer la première URL contenue dans le chaîne de caractère passée en argument
|
60
|
-
3. S'il s'agit d'une nouvelle URL, il envoie une requête $.post contenant l'URL extraite au service
|
61
|
-
4. Le retour de la requête est traitée :
|
62
|
-
a. Si le serveur retourne un code HTTP 200, le contenu de la réponse JSON est parsé et le callback appelé
|
63
|
-
b. Si le serveur retourne un code HTTP 404,
|
64
|
-
|
65
|
-
|
66
|
-
Example d'utilisation du plugin:
|
67
|
-
|
68
|
-
// On indique au parser l'URL du service
|
69
|
-
ContentPreview.service_url = 'http://example.com/content-preview-service'
|
70
|
-
var $textarea = $('textarea#user-content-input')
|
71
|
-
|
72
|
-
$textarea.on('keyup', function() {
|
73
|
-
$textarea.parseContentPreview($textarea.val(), function(resp) {
|
74
|
-
// Traitement de la réponse
|
75
|
-
});
|
76
|
-
});
|
77
|
-
|
78
|
-
----------------------------------------------------------------------
|
79
|
-
|
80
|
-
V.1 :
|
81
|
-
|
82
|
-
Une fois le service et le client JS testés complètement
|
83
|
-
|
84
|
-
----------------------------------------------------------------------
|
85
|
-
|
86
|
-
Idées supplémentaires :
|
87
|
-
|
88
|
-
- Mise en place d'un cache (probablement avec Redis) permettant de stocker le hash de réponse et de ne pas rechecker une URL si celle-ci a déjà été stockée. (Peut être avec un EXPIRE en fonction du cache ... à voir)
|
89
|
-
- Authentification au niveau du service
|
90
|
-
|