tinplate 1.0.2 → 2.0.2

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
- SHA1:
3
- metadata.gz: 1a614c00dcffdd96297cd2fbfa6982efb67ce878
4
- data.tar.gz: af55c37e079bd5131f540b7790c065897c11c9fa
2
+ SHA256:
3
+ metadata.gz: 4e646b162936b034d5e402b3c47957942019644a844c40ce643ce8606355b366
4
+ data.tar.gz: fb30461669218584c80330b21b1de6f0abb88686d687c2fef151a3bcbe573e66
5
5
  SHA512:
6
- metadata.gz: 879760416e70f064d0affe912a0f36584fbaa4c1f75ff42aa9c068e5a980510af94cfb8ed8fa43ce6d1083a1d7a108e081a593fd3aac7038ed1fc12ccec63983
7
- data.tar.gz: 0984d1d8b8eb99fce820388ea34513c826c15f6babcea769c501643c1a29cea17803e0e4137d92501fcc060bc524d78e87f515e028bfd349e2054fda94b2cb75
6
+ metadata.gz: 20a758012a6f63ad26b536f5f8fe3b9efd96bf43febc8f9ee11dec11c2f66245ec6280e6989549fca37521a8ac69087cebb4b10dad6198018d27e6f9143a93ac
7
+ data.tar.gz: da05c621d15de702343f62173df7f96e874b0ca3dfc0fa951403ec30648cf0d8d3f976335aa8b4f39a90ba63c95fa561f799f4a764b0e8c11d2af4a0bfdc67b4
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2016 Crew
3
+ Copyright (c) 2016 Unsplash
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -41,23 +41,30 @@ There are only three API actions available: `search`, `remaining_searches` (to c
41
41
 
42
42
  `image_count` returns a plain old integer.
43
43
 
44
- ### Search example
44
+ ### Search examples
45
45
 
46
- *Note: this gem does not (yet) support searching by image upload, only by image URL.*
46
+ #### Search by URL
47
47
 
48
48
  ```ruby
49
49
  tineye = Tinplate::TinEye.new
50
50
  results = tineye.search(image_url: "http://example.com/photo.jpg")
51
51
 
52
- results.total_results # => 2
53
- results.total_backlinks # => 3
54
- results.matches # => an Array of matched images (see below)
52
+ results.stats.total_results # => 2
53
+ results.stats.total_backlinks # => 3
54
+ results.matches # => an Array of matched images (see below)
55
55
 
56
56
  results.matches.each do |match|
57
57
  # Do what you like with this matched image. The world is your oyster.
58
58
  end
59
59
  ```
60
60
 
61
+ #### Search by upload
62
+
63
+ ```ruby
64
+ tineye = Tinplate::TinEye.new
65
+ results = tineye.search(image_path: "/home/alice/example.jpg")
66
+ ```
67
+
61
68
  #### Optional search parameters
62
69
 
63
70
  `offset`: Default 0
@@ -70,15 +77,20 @@ end
70
77
  An `OpenStruct` object with the following attributes (/w example values):
71
78
 
72
79
  ```ruby
80
+ domain: "ucsb.edu",
81
+ top_level_domain: "ucsb.edu",
73
82
  width: 400
74
83
  height: 300
75
- size: 50734
84
+ size: 50734,
85
+ filesize: 195840,
86
+ score: 88.9,
87
+ tags: ["collection"],
76
88
  image_url: "http://images.tineye.com/result/0f1e84b7b7538e8e7de048f4d45eb8f579e3e999941b3341ed9a754eb447ebb1",
77
89
  format: "JPEG",
78
90
  contributor: true,
79
91
  overlay: "overlay/507bb6bf9a397284e2330be7c0671aadc7319b4b/0f1e84b7b7538e8e7de048f4d45eb8f579e3e999941b3341ed9a754eb447ebb1?m21=-9.06952e-05&m22=0.999975&m23=0.0295591&m11=0.999975&m13=-0.0171177&m12=9.06952e-05",
80
92
  backlinks:
81
- # These are also an OpenStruct objects, not Hashes.
93
+ # These are also OpenStruct objects, not Hashes.
82
94
  [
83
95
  {
84
96
  url: "http://example-copier.com/photo.jpg",
@@ -1,12 +1,16 @@
1
1
  # https://services.tineye.com/developers/tineyeapi/authentication.html
2
2
 
3
+ require "securerandom"
4
+ require "uri"
5
+ require "openssl"
6
+
3
7
  module Tinplate
4
8
  class RequestAuthenticator
5
9
 
6
10
  def initialize(action, params = {}, image_name = "")
7
11
  @action = action
8
12
  @params = params
9
- @image_name = image_name
13
+ @image_name = image_name || ""
10
14
  @nonce = SecureRandom.hex
11
15
  @date = Time.now.to_i
12
16
  end
@@ -20,21 +24,29 @@ module Tinplate
20
24
  }
21
25
  end
22
26
 
27
+ def verb
28
+ @image_name.empty? ? "GET" : "POST"
29
+ end
30
+
31
+ def content_type
32
+ verb == "GET" ? "" : "multipart/form-data; boundary=-----------RubyMultipartPost"
33
+ end
34
+
23
35
  def signature_components
24
36
  [
25
37
  Tinplate.configuration.private_key,
26
- "GET",
27
- "", # Content-Type for GET requests is blank
28
- URI.encode(@image_name).downcase,
38
+ verb,
39
+ content_type,
40
+ URI.encode_www_form_component(@image_name).downcase,
29
41
  @date.to_i,
30
42
  @nonce,
31
- "http://api.tineye.com/rest/#{@action}/",
43
+ "https://api.tineye.com/rest/#{@action}/",
32
44
  hash_to_sorted_query_string(@params),
33
45
  ]
34
46
  end
35
47
 
36
48
  def signature
37
- OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha1"),
49
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"),
38
50
  Tinplate.configuration.private_key,
39
51
  signature_components.join)
40
52
  end
@@ -1,9 +1,8 @@
1
1
  module Tinplate
2
2
  class SearchResults < OpenStruct
3
3
  def initialize(data)
4
- super total_backlinks: data["total_backlinks"],
5
- total_results: data["total_results"],
6
- matches: parsed_matches(data["matches"])
4
+ super stats: OpenStruct.new(data["stats"]),
5
+ matches: parsed_matches(data["results"]["matches"])
7
6
  end
8
7
 
9
8
  private
@@ -3,34 +3,56 @@ module Tinplate
3
3
  SORTS = ["score", "size", "crawl_date"]
4
4
  ORDERS = ["asc", "desc"]
5
5
 
6
- def search(image_url: nil, offset: 0, limit: 100, sort: "score", order: "desc")
7
- raise ArgumentError.new("You must supply an image_url") if !image_url
6
+ def search(image_path: nil, image_url: nil, offset: 0, limit: 100, sort: "score", order: "desc")
7
+ raise ArgumentError.new("You must supply an image or image_url") if !image_url && !image_path
8
8
  raise ArgumentError.new("sort must be one of #{SORTS.join(', ')}") if !SORTS.include?(sort)
9
9
  raise ArgumentError.new("order must be one of #{ORDERS.join(', ')}") if !ORDERS.include?(order)
10
10
 
11
- response = request "search", image_url: image_url, offset: offset.to_s, limit: limit.to_s, sort: sort, order: order
12
- Tinplate::SearchResults.new(response["results"])
11
+ options = {
12
+ offset: offset.to_s,
13
+ limit: limit.to_s,
14
+ sort: sort,
15
+ order: order
16
+ }
17
+ img = image_url ? { image_url: image_url } : { image_path: image_path }
18
+
19
+ response = request("search", options.merge(img))
20
+
21
+ Tinplate::SearchResults.new(response)
13
22
  end
14
23
 
15
24
  def remaining_searches
16
25
  results = request("remaining_searches")["results"]
17
- OpenStruct.new(remaining_searches: results["remaining_searches"],
18
- start_date: DateTime.parse(results["start_date"]),
19
- expire_date: DateTime.parse(results["expire_date"]))
26
+
27
+ bundles = results["bundles"].map do |bundle|
28
+ OpenStruct.new(remaining_searches: bundle["remaining_searches"],
29
+ start_date: Time.parse(bundle["start_date"]),
30
+ expire_date: Time.parse(bundle["expire_date"]))
31
+ end
32
+
33
+ OpenStruct.new(total_remaining_searches: results["total_remaining_searches"], bundles: bundles)
20
34
  end
21
35
 
22
36
  def image_count
23
37
  request("image_count")["results"]
24
38
  end
25
39
 
26
-
27
40
  private
28
41
 
29
42
  def request(action, params = {})
30
- auth = Tinplate::RequestAuthenticator.new(action, params)
43
+ http_verb = :get
44
+
45
+ upload = if params[:image_path]
46
+ http_verb = :post
47
+ Faraday::UploadIO.new(params.delete(:image_path), "image/jpeg")
48
+ end
49
+
50
+ auth = Tinplate::RequestAuthenticator.new(action, params, upload && upload.original_filename)
31
51
  params.merge!(auth.params)
32
52
 
33
- response = ::JSON.parse(connection.get("#{action}/", params).body)
53
+ params.merge!(image_upload: upload) if upload
54
+
55
+ response = ::JSON.parse(connection.send(http_verb, "#{action}/", params).body)
34
56
 
35
57
  if response["code"] != 200
36
58
  raise Tinplate::Error.from_response(response["code"], response["messages"][0], response["messages"][1])
@@ -40,13 +62,13 @@ module Tinplate
40
62
  end
41
63
 
42
64
  def connection
43
- @conn ||= Faraday.new(url: "http://api.tineye.com/rest/") do |faraday|
65
+ @conn ||= Faraday.new(url: "https://api.tineye.com/rest/") do |faraday|
66
+ faraday.request :multipart
44
67
  faraday.request :url_encoded
45
- faraday.response :logger
46
68
  faraday.adapter Faraday.default_adapter
47
69
  end
48
70
  end
49
71
 
50
72
  end
51
73
 
52
- end
74
+ end
@@ -1,3 +1,3 @@
1
1
  module Tinplate
2
- VERSION = "1.0.2"
2
+ VERSION = "2.0.2"
3
3
  end
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
7
7
  spec.name = "tinplate"
8
8
  spec.version = Tinplate::VERSION
9
9
  spec.authors = ["Aaron Klaassen"]
10
- spec.email = ["aaron@crew.co"]
10
+ spec.email = ["aaron@unsplash.com"]
11
11
 
12
12
  spec.summary = %q{A wrapper around the TinEye API.}
13
13
  spec.homepage = "https://github.com/unsplash/tinplate"
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_dependency "faraday", "~> 0.9.2"
22
+ spec.add_dependency "faraday", [">= 0.9.2", "< 2.0.0"]
23
23
 
24
24
  spec.add_development_dependency "bundler", "~> 1.10"
25
25
  spec.add_development_dependency "rake", "~> 10.0"
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tinplate
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Klaassen
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-05-06 00:00:00.000000000 Z
11
+ date: 2020-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.9.2
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 2.0.0
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: 0.9.2
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 2.0.0
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: bundler
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -80,9 +86,9 @@ dependencies:
80
86
  - - ">="
81
87
  - !ruby/object:Gem::Version
82
88
  version: '0'
83
- description:
89
+ description:
84
90
  email:
85
- - aaron@crew.co
91
+ - aaron@unsplash.com
86
92
  executables: []
87
93
  extensions: []
88
94
  extra_rdoc_files: []
@@ -108,7 +114,7 @@ homepage: https://github.com/unsplash/tinplate
108
114
  licenses:
109
115
  - MIT
110
116
  metadata: {}
111
- post_install_message:
117
+ post_install_message:
112
118
  rdoc_options: []
113
119
  require_paths:
114
120
  - lib
@@ -123,9 +129,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
129
  - !ruby/object:Gem::Version
124
130
  version: '0'
125
131
  requirements: []
126
- rubyforge_project:
127
- rubygems_version: 2.4.8
128
- signing_key:
132
+ rubyforge_project:
133
+ rubygems_version: 2.7.10
134
+ signing_key:
129
135
  specification_version: 4
130
136
  summary: A wrapper around the TinEye API.
131
137
  test_files: []