yandex-webmaster 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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