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 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
-