rzoopla 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4b34d2b535148601f7ff4eb2e3fb4c91caf00556
4
+ data.tar.gz: 254d355bd399f74c3708782d98ba5616ccbbf6d3
5
+ SHA512:
6
+ metadata.gz: 1ee40c4dd967aae3a763e948d1b51f6a06b610a3fc3b4546482f6fb7a5141c7735358fdf639c1cc7fb302616df8e0eef3b1c44a04bb6789e0f63361a73181984
7
+ data.tar.gz: 02dae2e83184c814e20b373cc932b7e60ddbc5d79dd30d30eb030f2af31812c3f619794453fb777ab25b1dc816a8f25c2f3d7528b207af196c3f2e9eb46b3687
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,6 @@
1
+ Style/Documentation:
2
+ Enabled: false
3
+ Style/BlockDelimiters:
4
+ Enabled: false
5
+ Metrics/LineLength:
6
+ Max: 90
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rzoopla.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # RZoopla
2
+ ## Installation
3
+
4
+ Add this line to your application's Gemfile:
5
+
6
+ ```ruby
7
+ gem 'rzoopla'
8
+ ```
9
+
10
+ And then execute:
11
+
12
+ $ bundle
13
+
14
+ Or install it yourself as:
15
+
16
+ $ gem install rzoopla
17
+
18
+ ## Usage
19
+
20
+ RZoopla.configure do |config|
21
+ config.api_key = ENV['ZOOPLA_API_KEY']
22
+ end
23
+
24
+ RZoopla::Listings.where(
25
+ area: 'Edinburgh'
26
+ radius: 0.1,
27
+ order_by: 'age',
28
+ maximum_beds: 2,
29
+ listing_status: 'sale',
30
+ include_sold: 0
31
+ )
32
+
33
+ ## Contributing
34
+
35
+ 1. Fork it ( https://github.com/Omer/rzoopla/fork )
36
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
37
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
38
+ 4. Push to the branch (`git push origin my-new-feature`)
39
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'rzoopla'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/lib/rzoopla.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'net/http'
2
+ require 'cgi'
3
+ require 'json'
4
+ require 'rzoopla/version'
5
+ require 'rzoopla/utils'
6
+ require 'rzoopla/client'
7
+ require 'rzoopla/base_collection'
8
+ require 'rzoopla/base_model'
9
+ require 'rzoopla/resources'
10
+
11
+ module RZoopla
12
+ class << self
13
+ attr_accessor :configuration
14
+ end
15
+
16
+ def self.configure
17
+ self.configuration ||= Configuration.new
18
+ yield(configuration)
19
+ end
20
+
21
+ class Configuration
22
+ attr_accessor :api_key
23
+ end
24
+ end
@@ -0,0 +1,52 @@
1
+ module RZoopla
2
+ class BaseCollection
3
+ ATTRIBUTES = [:result_count, :page_number, :page_size, :results]
4
+ DEFAULT_PAGINATION_OPTIONS = {
5
+ page_number: 1,
6
+ page_size: 10
7
+ }
8
+
9
+ attr_reader(*ATTRIBUTES)
10
+
11
+ include Enumerable
12
+
13
+ def initialize(options = {})
14
+ ATTRIBUTES.each do |attr|
15
+ instance_variable_set("@#{attr}", options[attr])
16
+ end
17
+ end
18
+
19
+ def each(&block)
20
+ @results.each(&block)
21
+ end
22
+
23
+ def size
24
+ @results.size
25
+ end
26
+
27
+ def [](index)
28
+ @results[index]
29
+ end
30
+
31
+ def self.where(options = {})
32
+ opt = DEFAULT_PAGINATION_OPTIONS.clone.merge(options)
33
+ result = RZoopla::Utils.symbolize_keys(RZoopla::Client.get(end_point, opt))
34
+ new(
35
+ page_number: opt[:page_number],
36
+ page_size: opt[:page_size],
37
+ result_count: result[:result_count],
38
+ results: extract_results(result)
39
+ )
40
+ end
41
+
42
+ class << self
43
+ private
44
+
45
+ def extract_results(results)
46
+ results[results_field].map { |result| model.new(result) }
47
+ end
48
+
49
+ attr_accessor :end_point, :results_field, :model
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,23 @@
1
+ module RZoopla
2
+ class BaseModel
3
+ def initialize(options = {})
4
+ self.class.attributes.each do |attribute|
5
+ instance_variable_set("@#{attribute}", options[attribute])
6
+
7
+ self.class.send(:define_method, attribute) do
8
+ instance_variable_get("@#{attribute}")
9
+ end
10
+ end
11
+ end
12
+
13
+ def to_hash
14
+ Hash[*instance_variables.flat_map { |var|
15
+ [var.to_s.delete('@'), instance_variable_get(var)]
16
+ }]
17
+ end
18
+
19
+ class << self
20
+ attr_accessor :attributes
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ module RZoopla
2
+ module Client
3
+ class << self
4
+ BASE_URI = 'http://api.zoopla.co.uk/api/v1/'
5
+
6
+ def get(end_point, options = {})
7
+ options = { api_key: RZoopla.configuration.api_key }.merge(options)
8
+ uri = URI.parse([BASE_URI, end_point, '.json', parse_params(options)].join)
9
+ response = Net::HTTP.get_response(uri)
10
+ if response.code == '200'
11
+ JSON.parse(response.body)
12
+ else
13
+ fail "#{response.message} (#{response.code})"
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def parse_params(params)
20
+ return '' if params.empty?
21
+ '?' + params.map { |k, v|
22
+ "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"
23
+ }.join('&')
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,2 @@
1
+ require 'rzoopla/resources/listing'
2
+ require 'rzoopla/resources/listings'
@@ -0,0 +1,13 @@
1
+ module RZoopla
2
+ class Listing < RZoopla::BaseModel
3
+ self.attributes = [
4
+ :num_floors, :listing_status, :num_bedrooms, :latitude,
5
+ :agent_address, :property_type, :longitude, :thumbnail_url, :description,
6
+ :post_town, :details_url, :short_description, :outcode, :county, :price,
7
+ :listing_id, :image_caption, :status, :agent_name, :num_recepts,
8
+ :country, :displayable_address, :first_published_date, :price_modifier,
9
+ :floor_plan, :street_name, :num_bathrooms, :price_change, :agent_logo,
10
+ :agent_phone, :image_url, :last_published_date
11
+ ]
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ module RZoopla
2
+ class Listings < RZoopla::BaseCollection
3
+ self.end_point = 'property_listings'
4
+ self.results_field = :listing
5
+ self.model = RZoopla::Listing
6
+ end
7
+ end
@@ -0,0 +1,39 @@
1
+ module RZoopla
2
+ module Utils
3
+ class << self
4
+ def pluck(hash, *args)
5
+ Hash[hash.find_all { |k, _| args.include?(k) }]
6
+ end
7
+
8
+ def symbolize_keys(obj)
9
+ case obj
10
+ when Hash then symbolize_keys_hash(obj)
11
+ when Array then symbolize_keys_array(obj)
12
+ else obj
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def symbolize_keys_hash(hash)
19
+ hash.each_with_object({}) { |(key, value), result|
20
+ result[key.respond_to?(:to_sym) ? key.to_sym : key] = \
21
+ case value
22
+ when Hash then symbolize_keys_hash(value)
23
+ when Array then symbolize_keys_array(value)
24
+ else value
25
+ end
26
+ }
27
+ end
28
+
29
+ def symbolize_keys_array(array)
30
+ array.map { |el|
31
+ case el
32
+ when Hash then symbolize_keys_hash(el)
33
+ else el
34
+ end
35
+ }
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module RZoopla
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,52 @@
1
+ module RZoopla
2
+ class BaseCollection
3
+ ATTRIBUTES = [:result_count, :page_number, :page_size, :results]
4
+ DEFAULT_PAGINATION_OPTIONS = {
5
+ page_number: 1,
6
+ page_size: 10
7
+ }
8
+
9
+ attr_reader(*ATTRIBUTES)
10
+
11
+ include Enumerable
12
+
13
+ def initialize(options = {})
14
+ ATTRIBUTES.each do |attr|
15
+ instance_variable_set("@#{attr}", options[attr])
16
+ end
17
+ end
18
+
19
+ def each(&block)
20
+ @results.each(&block)
21
+ end
22
+
23
+ def size
24
+ @results.size
25
+ end
26
+
27
+ def [](index)
28
+ @results[index]
29
+ end
30
+
31
+ def self.where(options = {})
32
+ opt = DEFAULT_PAGINATION_OPTIONS.clone.merge(options)
33
+ result = RZoopla::Utils.symbolize_keys(RZoopla::Client.get(end_point, opt))
34
+ new(
35
+ page_number: opt[:page_number],
36
+ page_size: opt[:page_size],
37
+ result_count: result[:result_count],
38
+ results: extract_results(result)
39
+ )
40
+ end
41
+
42
+ class << self
43
+ private
44
+
45
+ def extract_results(results)
46
+ results[results_field].map { |result| model.new(result) }
47
+ end
48
+
49
+ attr_accessor :end_point, :results_field, :model
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,23 @@
1
+ module RZoopla
2
+ class BaseModel
3
+ def initialize(options = {})
4
+ self.class.attributes.each do |attribute|
5
+ instance_variable_set("@#{attribute}", options[attribute])
6
+
7
+ self.class.send(:define_method, attribute) do
8
+ instance_variable_get("@#{attribute}")
9
+ end
10
+ end
11
+ end
12
+
13
+ def to_hash
14
+ Hash[*instance_variables.flat_map { |var|
15
+ [var.to_s.delete('@'), instance_variable_get(var)]
16
+ }]
17
+ end
18
+
19
+ class << self
20
+ attr_accessor :attributes
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ module RZoopla
2
+ module Client
3
+ class << self
4
+ BASE_URI = 'http://api.zoopla.co.uk/api/v1/'
5
+
6
+ def get(end_point, options = {})
7
+ options = { api_key: RZoopla.configuration.api_key }.merge(options)
8
+ uri = URI.parse([BASE_URI, end_point, '.json', parse_params(options)].join)
9
+ response = Net::HTTP.get_response(uri)
10
+ if response.code == '200'
11
+ JSON.parse(response.body)
12
+ else
13
+ fail "#{response.message} (#{response.code})"
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def parse_params(params)
20
+ return '' if params.empty?
21
+ '?' + params.map { |k, v|
22
+ "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}"
23
+ }.join('&')
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,39 @@
1
+ module RZoopla
2
+ module Utils
3
+ class << self
4
+ def pluck(hash, *args)
5
+ Hash[hash.find_all { |k, _| args.include?(k) }]
6
+ end
7
+
8
+ def symbolize_keys(obj)
9
+ case obj
10
+ when Hash then symbolize_keys_hash(obj)
11
+ when Array then symbolize_keys_array(obj)
12
+ else obj
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def symbolize_keys_hash(hash)
19
+ hash.each_with_object({}) { |(key, value), result|
20
+ result[key.respond_to?(:to_sym) ? key.to_sym : key] = \
21
+ case value
22
+ when Hash then symbolize_keys_hash(value)
23
+ when Array then symbolize_keys_array(value)
24
+ else value
25
+ end
26
+ }
27
+ end
28
+
29
+ def symbolize_keys_array(array)
30
+ array.map { |el|
31
+ case el
32
+ when Hash then symbolize_keys_hash(el)
33
+ else el
34
+ end
35
+ }
36
+ end
37
+ end
38
+ end
39
+ end
data/rzoopla.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rzoopla/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'rzoopla'
8
+ spec.version = RZoopla::VERSION
9
+ spec.authors = ['Omer Jakobinsky']
10
+ spec.email = ['omer@jakobinsky.com']
11
+
12
+ spec.summary = 'A Ruby wrapper for the Zoopla API.'
13
+ spec.description = 'A work in progress Ruby wrapper for the Zoopla API.'
14
+ spec.homepage = 'https://github.com/Omer/rzoopla'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ }
19
+ spec.bindir = 'exe'
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.add_development_dependency 'bundler', '~> 1.9'
24
+ spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'rubocop', '~> 0.30'
26
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rzoopla
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Omer Jakobinsky
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-04-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.9'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.30'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.30'
55
+ description: A work in progress Ruby wrapper for the Zoopla API.
56
+ email:
57
+ - omer@jakobinsky.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".rubocop.yml"
65
+ - ".travis.yml"
66
+ - Gemfile
67
+ - README.md
68
+ - Rakefile
69
+ - bin/console
70
+ - bin/setup
71
+ - lib/rzoopla.rb
72
+ - lib/rzoopla/base_collection.rb
73
+ - lib/rzoopla/base_model.rb
74
+ - lib/rzoopla/client.rb
75
+ - lib/rzoopla/resources.rb
76
+ - lib/rzoopla/resources/listing.rb
77
+ - lib/rzoopla/resources/listings.rb
78
+ - lib/rzoopla/utils.rb
79
+ - lib/rzoopla/version.rb
80
+ - lib/zoopla/base_collection.rb
81
+ - lib/zoopla/base_model.rb
82
+ - lib/zoopla/client.rb
83
+ - lib/zoopla/utils.rb
84
+ - rzoopla.gemspec
85
+ homepage: https://github.com/Omer/rzoopla
86
+ licenses: []
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 2.4.6
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: A Ruby wrapper for the Zoopla API.
108
+ test_files: []