picture_from 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 11924f08d55e6f4104bc764e3ee2f49de4a130ac
4
- data.tar.gz: 7396b3c9329034a6caf1853ff70b49bada0513cd
3
+ metadata.gz: cb7f865aafa5ad8a359f4a3c9cbf3bcdfc9f19b4
4
+ data.tar.gz: 5d8e3f71b4186d10eaf1ab0c218ba61d2bdb1c32
5
5
  SHA512:
6
- metadata.gz: e5fc95bfdf460835a048601f91f5aff3db9b20ce6a284ce56317de19ce8772e586cecde541e30f38295caddc1ea949373aeba2401bbc78ccb189cb496a3e2676
7
- data.tar.gz: ece08909c8b2b98d9eea91c57af861d7f2e7b683f45000c8a28c100e0164f5b90192196d05b9f150b41fb41deb3eafbe2ea67cbfe613422fb4291aea4e2d4c9e
6
+ metadata.gz: d2ae1cc6afd91c116577c9c5ffc4b4c6cba109282258a27a68cca707c3f093dbd6f7f6168e82a5308a5ffe1490dfe1e3cbefe4fe46d241d9b1939acba9b228e9
7
+ data.tar.gz: 6fa907f00f53441ade90e99257fed809af8964fab8475c696a40cbf57b96d0f20f0d2ec5632fb169d9fb6a872864e4b4d9620e6191e2e30f67078e05a10b9b4f
data/.travis.yml CHANGED
@@ -9,5 +9,4 @@ notifications:
9
9
  on_failure: change
10
10
 
11
11
  script:
12
- - bundle exec rspec
13
- - bundle exec rubocop
12
+ - bundle exec rake ci
data/README.md CHANGED
@@ -29,21 +29,15 @@ PictureFrom.url('karreiro')
29
29
 
30
30
  Engines
31
31
  ------------
32
- PicutreFrom has many engines for finding the appropriete image for any user in your application:
32
+ PicutreFrom has many engines for finding the appropriate image for any user in your application:
33
33
 
34
34
  - Gravatar
35
- - by e-mail
36
- - by GitHub username
35
+ - by e-mail
37
36
  - Facebook
38
- - by username ✔
39
- - by e-mail ✔
40
- - by user information ✔
41
- - Twitter
42
37
  - by username
38
+ - by e-mail
43
39
  - by user information
44
- - Linkedin
45
- - by username
46
- - Ello
40
+ - Twitter
47
41
  - by username
48
42
 
49
43
  Contributing
data/Rakefile CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env rake
2
2
  require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
3
4
 
4
5
  begin
5
6
  Bundler.setup :default, :development
@@ -17,6 +18,13 @@ task :coverage do
17
18
  end
18
19
 
19
20
  RSpec::Core::RakeTask.new(:spec)
21
+ RuboCop::RakeTask.new(:rubocop)
20
22
 
21
23
  desc 'Default: run tests'
22
24
  task default: [:spec]
25
+
26
+ desc 'C.I: run tests and rubocop'
27
+ task :ci do
28
+ Rake::Task['rubocop'].execute
29
+ Rake::Task['spec'].execute
30
+ end
@@ -0,0 +1,23 @@
1
+ require 'open-uri'
2
+ require 'nokogiri'
3
+
4
+ module PictureFrom
5
+ module Apis
6
+ class FacebookApi
7
+
8
+ # TODO: Use the http://graph.facebook.com/karreiro/picture?redirect=false
9
+ # API to identify silhouette pictures.
10
+ def image_url_by_username(username)
11
+ url = "http://graph.facebook.com/#{username}/picture"
12
+ open URI.escape(url)
13
+ rescue OpenURI::HTTPError
14
+ # handle 404 and 400
15
+ nil
16
+ rescue RuntimeError
17
+ # handle 302
18
+ url
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ require 'open-uri'
2
+ require 'nokogiri'
3
+
4
+ module PictureFrom
5
+ module Crawlers
6
+ class BaseCrawler
7
+
8
+ class Page
9
+ def open_url(url)
10
+ uri = URI.escape(url)
11
+ Nokogiri::HTML open(uri)
12
+ rescue OpenURI::HTTPError
13
+ nil
14
+ end
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -1,27 +1,31 @@
1
- require 'open-uri'
2
- require 'nokogiri'
3
-
4
1
  module PictureFrom
5
2
  module Crawlers
6
3
  class FacebookCrawler
7
4
 
8
- def query(keyword)
9
- page = search_page(keyword)
10
- results = page.css('#pagelet_search_results .instant_search_title a')
11
- username_from_url(results.first['href']) if results.size > 0
5
+ def image_url_by_user_info(user_info)
6
+ page = SearchPage.new(user_info)
7
+ page.usernames.first
12
8
  end
13
9
 
14
- private
10
+ class SearchPage < BaseCrawler::Page
11
+ def initialize(user_info)
12
+ @page = open_url("https://www.facebook.com/search.php?q=#{user_info}")
13
+ end
15
14
 
16
- def search_page(query)
17
- search_page_url = "https://www.facebook.com/search.php?q=#{query}"
18
- Nokogiri::HTML open(search_page_url)
19
- end
15
+ def usernames
16
+ results.map { |result| username_from_url(result['href']) }.compact
17
+ end
18
+
19
+ private
20
+
21
+ def username_from_url(url)
22
+ match = %r{^https?://(www\.)?facebook.com/(?<u>[^/\.]*)/?$}.match(url)
23
+ match[:u] if match
24
+ end
20
25
 
21
- def username_from_url(url)
22
- url_regex = %r{^https?://(www\.)?facebook.com/(?<username>[^/\.]*)}
23
- match = url_regex.match(url)
24
- match[:username] if match
26
+ def results
27
+ @page.css('#pagelet_search_results .instant_search_title a')
28
+ end
25
29
  end
26
30
 
27
31
  end
@@ -0,0 +1,22 @@
1
+ module PictureFrom
2
+ module Crawlers
3
+ class TwitterCrawler
4
+
5
+ def image_url_by_username(username)
6
+ page = ProfilePage.new(username)
7
+ page.avatar_image
8
+ end
9
+
10
+ class ProfilePage < BaseCrawler::Page
11
+ def initialize(username)
12
+ @page = open_url("https://twitter.com/#{username}")
13
+ end
14
+
15
+ def avatar_image
16
+ @page.css('.ProfileAvatar-image').first['src'] if @page
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -3,14 +3,15 @@ module PictureFrom
3
3
 
4
4
  def initialize
5
5
  @facebook_crawler = Crawlers::FacebookCrawler.new
6
+ @facebook_api = Apis::FacebookApi.new
6
7
  end
7
8
 
8
9
  def picture_from_username(username)
9
- "http://graph.facebook.com/#{username}/picture"
10
+ @facebook_api.image_url_by_username(username)
10
11
  end
11
12
 
12
13
  def picture_from_user_info(user_info)
13
- username = @facebook_crawler.query(user_info)
14
+ username = @facebook_crawler.image_url_by_user_info(user_info)
14
15
  picture_from_username(username)
15
16
  end
16
17
 
@@ -3,6 +3,8 @@ require 'digest/md5'
3
3
  module PictureFrom
4
4
  class GravatarPicture
5
5
 
6
+ # TODO: Gravatar always returns an image. The default Gravatar image should
7
+ # be rejected.
6
8
  def picture_from_email(email)
7
9
  "http://www.gravatar.com/avatar/#{digest(email)}"
8
10
  end
@@ -0,0 +1,22 @@
1
+ module PictureFrom
2
+ class Keyword
3
+
4
+ attr_reader :value
5
+
6
+ def initialize(value)
7
+ @value = value
8
+ end
9
+
10
+ def type
11
+ case value
12
+ when /^@?([\w\.])*$/
13
+ :username
14
+ when /.+@.+/
15
+ :email
16
+ else
17
+ :user_info
18
+ end
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,44 @@
1
+ module PictureFrom
2
+ class SearchEngine
3
+
4
+ DEFAULT_RULES = {
5
+ username: [
6
+ { facebook: :picture_from_username },
7
+ { twitter: :picture_from_username },
8
+ { facebook: :picture_from_user_info }
9
+ ],
10
+ email: [
11
+ { gravatar: :picture_from_email },
12
+ { facebook: :picture_from_user_info }
13
+ ],
14
+ user_info: [
15
+ { facebook: :picture_from_user_info }
16
+ ]
17
+ }
18
+
19
+ def initialize(keyword_value = '')
20
+ @keyword = Keyword.new(keyword_value)
21
+ end
22
+
23
+ def image_url
24
+ default_rules.each do |rule|
25
+ rule.each do |provider, method|
26
+ image_url = initialize_provider(provider).send(method, @keyword.value)
27
+ return image_url if image_url
28
+ end
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def default_rules
35
+ DEFAULT_RULES[@keyword.type]
36
+ end
37
+
38
+ def initialize_provider(provider)
39
+ provider_name = "#{provider.capitalize}Picture"
40
+ PictureFrom.const_get(provider_name).new
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,13 @@
1
+ module PictureFrom
2
+ class TwitterPicture
3
+
4
+ def initialize
5
+ @twitter_crawler = Crawlers::TwitterCrawler.new
6
+ end
7
+
8
+ def picture_from_username(username)
9
+ @twitter_crawler.image_url_by_username(username)
10
+ end
11
+
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module PictureFrom
2
- VERSION = '0.0.1'
2
+ VERSION = '1.0.0'
3
3
  end
data/lib/picture_from.rb CHANGED
@@ -1,7 +1,18 @@
1
+ require 'picture_from/crawlers/base_crawler'
1
2
  require 'picture_from/crawlers/facebook_crawler'
3
+ require 'picture_from/crawlers/twitter_crawler'
4
+ require 'picture_from/apis/facebook_api'
2
5
  require 'picture_from/facebook_picture'
3
6
  require 'picture_from/gravatar_picture'
7
+ require 'picture_from/twitter_picture'
8
+ require 'picture_from/search_engine'
9
+ require 'picture_from/keyword'
4
10
 
5
11
  module PictureFrom
6
- # TODO
12
+
13
+ def self.url(keyword_value)
14
+ search_engine = SearchEngine.new(keyword_value)
15
+ search_engine.image_url
16
+ end
17
+
7
18
  end