content-preview 0.0.1 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -2,4 +2,6 @@ source "http://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
+ ruby '1.9.3'
6
+
5
7
  gem 'rspec'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- content-preview (0.0.1)
4
+ content-preview (0.1.1)
5
5
  json
6
6
  nokogiri
7
7
  rack-cors
@@ -0,0 +1 @@
1
+ web: bundle exec rackup config.ru -p $PORT
@@ -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 "start", "Starts a Rack server with the Rack::Handler and Port given as argument Defaults are Webrick and"
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
- app = Rack::Builder.new do
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(app, Host: '0.0.0.0', Port: port)
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
@@ -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 = `git ls-files`.split("\n")
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
- result['title'] = self.title
22
- result['description'] = self.description
23
- result['images'] = self.images
24
-
25
- return result
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
@@ -1,3 +1,3 @@
1
1
  module ContentPreview
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -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
- {"title"=>"The Artist - Official Trailer [HD]", "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: ...", "images"=>["http://i4.ytimg.com/vi/OK7pfLlsUQM/mqdefault.jpg"]}
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.0.1
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-24 00:00:00.000000000 Z
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: 1542849611858236016
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: 1542849611858236016
161
+ hash: -3903559105997768296
164
162
  requirements: []
165
163
  rubyforge_project:
166
- rubygems_version: 1.8.23
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
@@ -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
-