yandex-webmaster 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.
Files changed (49) hide show
  1. data/.document +5 -0
  2. data/Gemfile +23 -0
  3. data/Gemfile.lock +72 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.md +259 -0
  6. data/Rakefile +46 -0
  7. data/lib/yandex-webmaster.rb +80 -0
  8. data/lib/yandex-webmaster/api/attributes.rb +23 -0
  9. data/lib/yandex-webmaster/api/attributes/accessor_builder.rb +59 -0
  10. data/lib/yandex-webmaster/api/attributes/reader_builder.rb +35 -0
  11. data/lib/yandex-webmaster/api/attributes/types/base.rb +27 -0
  12. data/lib/yandex-webmaster/api/attributes/types/boolean.rb +22 -0
  13. data/lib/yandex-webmaster/api/attributes/types/date.rb +17 -0
  14. data/lib/yandex-webmaster/api/attributes/types/date_time.rb +17 -0
  15. data/lib/yandex-webmaster/api/attributes/types/float.rb +17 -0
  16. data/lib/yandex-webmaster/api/attributes/types/integer.rb +17 -0
  17. data/lib/yandex-webmaster/api/attributes/types/symbol.rb +17 -0
  18. data/lib/yandex-webmaster/api/attributes/types/time.rb +17 -0
  19. data/lib/yandex-webmaster/api/attributes/writer_builder.rb +36 -0
  20. data/lib/yandex-webmaster/api/attributes_builder.rb +65 -0
  21. data/lib/yandex-webmaster/api_factory.rb +32 -0
  22. data/lib/yandex-webmaster/authorization.rb +59 -0
  23. data/lib/yandex-webmaster/base.rb +120 -0
  24. data/lib/yandex-webmaster/client.rb +16 -0
  25. data/lib/yandex-webmaster/configuration.rb +99 -0
  26. data/lib/yandex-webmaster/connection.rb +87 -0
  27. data/lib/yandex-webmaster/core_ext/array.rb +23 -0
  28. data/lib/yandex-webmaster/core_ext/class.rb +55 -0
  29. data/lib/yandex-webmaster/core_ext/date.rb +7 -0
  30. data/lib/yandex-webmaster/core_ext/date_time.rb +7 -0
  31. data/lib/yandex-webmaster/core_ext/hash.rb +92 -0
  32. data/lib/yandex-webmaster/core_ext/nil_class.rb +7 -0
  33. data/lib/yandex-webmaster/core_ext/object.rb +19 -0
  34. data/lib/yandex-webmaster/core_ext/string.rb +23 -0
  35. data/lib/yandex-webmaster/errors.rb +23 -0
  36. data/lib/yandex-webmaster/host.rb +220 -0
  37. data/lib/yandex-webmaster/hosts/crawling.rb +26 -0
  38. data/lib/yandex-webmaster/hosts/sitemap.rb +73 -0
  39. data/lib/yandex-webmaster/hosts/sitemap_info.rb +55 -0
  40. data/lib/yandex-webmaster/hosts/top_info.rb +19 -0
  41. data/lib/yandex-webmaster/hosts/verification.rb +81 -0
  42. data/lib/yandex-webmaster/request.rb +62 -0
  43. data/lib/yandex-webmaster/request/oauth2.rb +28 -0
  44. data/lib/yandex-webmaster/response/hashify.rb +59 -0
  45. data/lib/yandex-webmaster/version.rb +14 -0
  46. data/test/helper.rb +18 -0
  47. data/test/test_webmaster.rb +7 -0
  48. data/yandex-webmaster.gemspec +167 -0
  49. metadata +546 -0
@@ -0,0 +1,120 @@
1
+ # encoding: utf-8
2
+
3
+ require 'yandex-webmaster/configuration'
4
+
5
+ require 'yandex-webmaster/authorization'
6
+ require 'yandex-webmaster/connection'
7
+ require 'yandex-webmaster/request'
8
+
9
+ module Yandex
10
+ module Webmaster
11
+ class Base
12
+ include Authorization
13
+ include Connection
14
+ include Request
15
+
16
+ class << self
17
+ def define_attributes(options = {}, &block)
18
+ options[:as] ||= :attributes
19
+
20
+ cattr_accessor options[:as].to_sym
21
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
22
+ @@#{options[:as].to_s} ||= {}
23
+ EOS
24
+
25
+ unless options[:inspect] == false
26
+ define_method(:inspect) do
27
+ inspection = self.send(options[:as].to_s).map { |key, value|
28
+ self.inspect_attribute(key, value[:instance_variable_name])
29
+ }.compact.join(', ')
30
+
31
+ "#<#{self.class} #{inspection}>"
32
+ end
33
+
34
+ define_method(:inspect_attribute) do |attribute_name, instance_variable_name|
35
+ value = instance_variable_get(instance_variable_name.to_s)
36
+
37
+ if value.is_a?(String) && value.length > 50
38
+ "#{attribute_name.to_s}[#{value.size}]: " + "#{value[0..50]}...".inspect
39
+ elsif value.is_a?(Array) && value.length > 5
40
+ "#{attribute_name.to_s}[#{value.size}]: " + "#{value[0..5]}...".inspect
41
+ else
42
+ "#{attribute_name.to_s}: " + value.inspect
43
+ end
44
+ end
45
+
46
+ end
47
+
48
+ Yandex::Webmaster::Api::AttributesBuilder.new(self, options, &block)
49
+ end
50
+
51
+ def const_missing(name)
52
+ Yandex::Webmaster::Api::AttributesBuilder.cast_type(name) || super
53
+ end
54
+ end
55
+
56
+ attr_accessor :configuration
57
+
58
+ def initialize(attributes = {})
59
+ self.attributes = attributes
60
+ end
61
+
62
+ def attributes=(attributes = {})
63
+ attributes.each do |attr,value|
64
+ self.send("#{attr}=", value) if self.respond_to?("#{attr}=")
65
+ end
66
+ end
67
+
68
+ def configuration=(value)
69
+ value = Yandex::Webmaster::Configuration.new(value) if !value.is_a?(Yandex::Webmaster::Configuration)
70
+ @configuration = value
71
+ end
72
+
73
+ # Responds to attribute query or attribute clear
74
+ def method_missing(method, *args, &block) # :nodoc:
75
+ case method.to_s
76
+ when /^(.*)\?$/
77
+ return !!self.send($1.to_s)
78
+ when /^clear_(.*)$/
79
+ self.send("#{$1.to_s}=", nil)
80
+ else
81
+ super
82
+ end
83
+ end
84
+
85
+ # Acts as setter and getter for api requests arguments parsing.
86
+ #
87
+ # Returns Arguments instance.
88
+ #
89
+ # def arguments(args=(not_set = true), options={}, &block)
90
+ # if not_set
91
+ # @arguments
92
+ # else
93
+ # @arguments = Arguments.new(self, options).parse(*args, &block)
94
+ # end
95
+ # end
96
+
97
+ protected
98
+
99
+ def objects_from_response(klass, response, prefix)
100
+ self.objects_from_array(klass, self.fetch_value(response, prefix))
101
+ end
102
+
103
+ def fetch_value(response, prefix)
104
+ response.body[prefix]
105
+ end
106
+
107
+ # @param klass [Class]
108
+ # @param array [Array]
109
+ # @return [Array<Class>]
110
+ def objects_from_array(klass, array)
111
+ array.map do |attributes|
112
+ instance = klass.new
113
+ instance.configuration = self.configuration
114
+ instance.attributes = attributes
115
+ instance
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+
3
+ module Yandex
4
+ module Webmaster
5
+ class Client < Base
6
+ def hosts(reload = false)
7
+ @hosts = nil if reload
8
+ @hosts ||= Yandex::Webmaster::ApiFactory.new({
9
+ :klass => Yandex::Webmaster::Host,
10
+ :url => '/hosts',
11
+ :configuration => self.configuration
12
+ })
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,99 @@
1
+ # encoding: utf-8
2
+
3
+ require 'singleton'
4
+
5
+ module Yandex
6
+ module Webmaster
7
+ class Configuration
8
+ VALID_OPTIONS_KEYS = [
9
+ :adapter,
10
+ :app_id,
11
+ :app_password,
12
+ :oauth_token,
13
+ :endpoint,
14
+ :site,
15
+ :ssl,
16
+ :user_agent,
17
+ :connection_options
18
+ ].freeze
19
+
20
+ # Other adapters are :typhoeus, :patron, :em_synchrony, :excon, :test
21
+ DEFAULT_ADAPTER = :net_http
22
+
23
+ # By default, don't set an application id
24
+ DEFAULT_APP_ID = nil
25
+
26
+ # By default, don't set an application password
27
+ DEFAULT_APP_PASSWORD = nil
28
+
29
+ # By default, don't set a user oauth access token
30
+ DEFAULT_OAUTH_TOKEN = nil
31
+
32
+ # The api endpoint used to connect to Yandex.Webmaster if none is set
33
+ DEFAULT_ENDPOINT = 'https://webmaster.yandex.ru/api/v2/'.freeze
34
+
35
+ # The web endpoint used to connect to Yandex.Webmaster if none is set
36
+ DEFAULT_SITE = 'https://oauth.yandex.ru/'.freeze
37
+
38
+ # The default SSL configuration
39
+ DEFAULT_SSL = {}
40
+
41
+ # The value sent in the http header for 'User-Agent' if none is set
42
+ DEFAULT_USER_AGENT = "Webmaster Ruby Gem #{Yandex::Webmaster::Version::STRING}".freeze
43
+
44
+ # By default uses the Faraday connection options if none is set
45
+ DEFAULT_CONNECTION_OPTIONS = {}
46
+
47
+ attr_accessor *VALID_OPTIONS_KEYS
48
+
49
+ def initialize(options = {})
50
+ raise ArgumentError if (options.symbolize_keys!.keys - VALID_OPTIONS_KEYS).any?
51
+
52
+ self.reset!
53
+ options.each { |k,v| send("#{k}=", v) }
54
+ end
55
+
56
+ def keys
57
+ VALID_OPTIONS_KEYS
58
+ end
59
+
60
+ def current
61
+ VALID_OPTIONS_KEYS.inject({}) { |h, k| h[k] = send(k); h }
62
+ end
63
+
64
+ # Reset configuration options to their defaults
65
+ #
66
+ def reset!
67
+ self.adapter = DEFAULT_ADAPTER
68
+ self.app_id = DEFAULT_APP_ID
69
+ self.app_password = DEFAULT_APP_PASSWORD
70
+ self.oauth_token = DEFAULT_OAUTH_TOKEN
71
+ self.endpoint = DEFAULT_ENDPOINT
72
+ self.site = DEFAULT_SITE
73
+ self.ssl = DEFAULT_SSL
74
+ self.user_agent = DEFAULT_USER_AGENT
75
+ self.connection_options = DEFAULT_CONNECTION_OPTIONS
76
+ self
77
+ end
78
+
79
+ # Convenience method to allow for global setting of configuration options
80
+ #
81
+ def configure
82
+ yield self
83
+ end
84
+
85
+ # Responds to attribute query or attribute clear
86
+ #
87
+ def method_missing(method, *args, &block) # :nodoc:
88
+ case method.to_s
89
+ when /^(.*)\?$/
90
+ return !!self.send($1.to_s)
91
+ when /^clear_(.*)$/
92
+ self.send("#{$1.to_s}=", nil)
93
+ else
94
+ super
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,87 @@
1
+ # encoding: utf-8
2
+
3
+ require 'faraday'
4
+
5
+ module Yandex
6
+ module Webmaster
7
+ module Connection
8
+ extend self
9
+
10
+ USER_AGENT = 'User-Agent'.freeze
11
+
12
+ ACCEPT = 'Accept'.freeze
13
+
14
+ ACCEPT_CHARSET = 'Accept-Charset'.freeze
15
+
16
+ CONTENT_TYPE = 'Content-Type'.freeze
17
+
18
+ ALLOWED_OPTIONS = [
19
+ :headers,
20
+ :url,
21
+ :params,
22
+ :request,
23
+ :ssl
24
+ ].freeze
25
+
26
+ # Returns a Fraday::Connection object
27
+ #
28
+ def connection(options = {})
29
+
30
+ options = self.connection_options(options)
31
+
32
+ if @connection_options != options
33
+ @connection = nil
34
+ @connection_options = options
35
+ end
36
+
37
+ @connection ||= Faraday.new(@connection_options.merge(:builder => self.stack))
38
+ end
39
+
40
+ protected
41
+
42
+ def connection_options(options = {})
43
+ options.slice!(*ALLOWED_OPTIONS)
44
+
45
+ {
46
+ :headers => {
47
+ ACCEPT_CHARSET => "utf-8",
48
+ USER_AGENT => self.configuration.user_agent,
49
+ # Due to error in Yandex.Webmaster API I had to change this header
50
+ # http://clubs.ya.ru/webmaster-api/replies.xml?item_no=150
51
+ # CONTENT_TYPE => 'application/xml'
52
+ CONTENT_TYPE => 'application/x-www-form-urlencoded'
53
+ },
54
+ :ssl => options.fetch(:ssl) { self.configuration.ssl },
55
+ :url => options.fetch(:endpoint) { self.configuration.endpoint }
56
+ }.merge(options)
57
+ end
58
+
59
+ # Exposes middleware builder to facilitate custom stacks and easy
60
+ # addition of new extensions such as cache adapter.
61
+ #
62
+ def stack(&block)
63
+ @stack ||= begin
64
+ block_given? ? Faraday::Builder.new(&block) : Faraday::Builder.new(&default_middleware)
65
+ end
66
+ end
67
+
68
+ # Default middleware stack that uses default adapter as specified at
69
+ # configuration stage.
70
+ #
71
+ def default_middleware
72
+ Proc.new do |builder|
73
+ builder.use Faraday::Request::Multipart
74
+ builder.use Faraday::Request::UrlEncoded
75
+ builder.use Yandex::Webmaster::Request::OAuth2, self.configuration.oauth_token
76
+
77
+ builder.use Faraday::Response::Logger if ENV['DEBUG']
78
+ builder.use Yandex::Webmaster::Response::Hashify
79
+ # builder.use Yandex::Webmaster::Response::RaiseError
80
+
81
+ builder.adapter self.configuration.adapter
82
+ end
83
+ end
84
+
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ class Array # :nodoc:
4
+ def extract_options!
5
+ if last.is_a?(Hash) && last.extractable_options?
6
+ pop
7
+ else
8
+ {}
9
+ end
10
+ end unless method_defined?(:extract_options!)
11
+
12
+ class << self
13
+ def wrap(object)
14
+ if object.nil?
15
+ []
16
+ elsif object.respond_to?(:to_ary)
17
+ object.to_ary || [object]
18
+ else
19
+ [object]
20
+ end
21
+ end unless method_defined?(:wrap)
22
+ end
23
+ end
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+
3
+ class Class
4
+ def cattr_reader(*syms)
5
+ options = syms.extract_options!
6
+ syms.each do |sym|
7
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
8
+ unless defined? @@#{sym}
9
+ @@#{sym} = nil
10
+ end
11
+
12
+ def self.#{sym}
13
+ @@#{sym}
14
+ end
15
+ EOS
16
+
17
+ unless options[:instance_reader] == false || options[:instance_accessor] == false
18
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
19
+ def #{sym}
20
+ @@#{sym}
21
+ end
22
+ EOS
23
+ end
24
+ end
25
+ end unless method_defined?(:cattr_reader)
26
+
27
+ def cattr_writer(*syms)
28
+ options = syms.extract_options!
29
+ syms.each do |sym|
30
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
31
+ unless defined? @@#{sym}
32
+ @@#{sym} = nil
33
+ end
34
+
35
+ def self.#{sym}=(obj)
36
+ @@#{sym} = obj
37
+ end
38
+ EOS
39
+
40
+ unless options[:instance_writer] == false || options[:instance_accessor] == false
41
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
42
+ def #{sym}=(obj)
43
+ @@#{sym} = obj
44
+ end
45
+ EOS
46
+ end
47
+ self.send("#{sym}=", yield) if block_given?
48
+ end
49
+ end unless method_defined?(:cattr_writer)
50
+
51
+ def cattr_accessor(*syms, &blk)
52
+ cattr_reader(*syms)
53
+ cattr_writer(*syms, &blk)
54
+ end unless method_defined?(:cattr_accessor)
55
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ class Date
4
+ def inspect
5
+ self.strftime("%a, %d %b %Y")
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ class DateTime
4
+ def inspect
5
+ self.strftime("%a, %d %b %Y %H:%M:%S %z")
6
+ end
7
+ end
@@ -0,0 +1,92 @@
1
+ # encoding: utf-8
2
+
3
+ class Hash # :nodoc:
4
+ def except(*items) # :nodoc:
5
+ self.dup.except!(*items)
6
+ end unless method_defined?(:except)
7
+
8
+ def except!(*keys) # :nodoc:
9
+ copy = self.dup
10
+ keys.each { |key| copy.delete!(key) }
11
+ copy
12
+ end unless method_defined?(:except!)
13
+
14
+ def slice(*keys)
15
+ keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
16
+ hash = self.class.new
17
+ keys.each { |k| hash[k] = self[k] if has_key?(k) }
18
+ hash
19
+ end unless method_defined?(:slice)
20
+
21
+ def slice!(*keys)
22
+ keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
23
+ omit = slice(*self.keys - keys)
24
+ hash = slice(*keys)
25
+ replace(hash)
26
+ omit
27
+ end unless method_defined?(:slice!)
28
+
29
+ def symbolize_keys # :nodoc:
30
+ inject({}) do |hash, (key, value)|
31
+ hash[(key.to_sym rescue key) || key] = value
32
+ hash
33
+ end
34
+ end unless method_defined?(:symbolize_keys)
35
+
36
+ def symbolize_keys! # :nodoc:
37
+ hash = symbolize_keys
38
+ hash.each do |key, val|
39
+ hash[key] = case val
40
+ when Hash
41
+ val.symbolize_keys!
42
+ when Array
43
+ val.map do |item|
44
+ item.is_a?(Hash) ? item.symbolize_keys! : item
45
+ end
46
+ else
47
+ val
48
+ end
49
+ end
50
+ return hash
51
+ end unless method_defined?(:symbolize_keys!)
52
+
53
+ def extractable_options?
54
+ instance_of?(Hash)
55
+ end unless method_defined?(:extractable_options?)
56
+
57
+ def serialize # :nodoc:
58
+ self.map { |key, val| [key, val].join("=") }.join("&")
59
+ end unless method_defined?(:serialize)
60
+
61
+ def all_keys # :nodoc:
62
+ keys = self.keys
63
+ keys.each do |key|
64
+ if self[key].is_a?(Hash)
65
+ keys << self[key].all_keys.compact.flatten
66
+ next
67
+ end
68
+ end
69
+ keys.flatten
70
+ end unless method_defined?(:all_keys)
71
+
72
+ def has_deep_key?(key)
73
+ self.all_keys.include? key
74
+ end unless method_defined?(:has_deep_key?)
75
+
76
+ def self.hash_traverse(hash, &block)
77
+ hash.each do |key, val|
78
+ block.call(key)
79
+ case val
80
+ when Hash
81
+ val.keys.each do |k|
82
+ _hash_traverse(val, &block)
83
+ end
84
+ when Array
85
+ val.each do |item|
86
+ _hash_traverse(item, &block)
87
+ end
88
+ end
89
+ end
90
+ return hash
91
+ end
92
+ end # Hash