picture_from 0.0.1 → 1.0.0

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