nineflats-api 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,3 +2,4 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ .rvmrc
data/Gemfile CHANGED
@@ -1,6 +1,2 @@
1
1
  source "http://rubygems.org"
2
-
3
2
  gemspec
4
-
5
- gem 'rspec'
6
- gem 'fakeweb'
data/README.md ADDED
@@ -0,0 +1,15 @@
1
+ Read about the API here: http://9flats.github.com/api_docs/
2
+
3
+ ### How to update this gem
4
+
5
+ $ git clone git@github.com:9flats/nineflats-api.git
6
+
7
+ [make your changes]
8
+
9
+ $ git commit -am "my changes"
10
+ $ git push
11
+ $ rake install
12
+ $ gem push pkg/nineflats-api-0.0.3.gem
13
+
14
+ When you push a new gem version, update the [nineflats-api-example](https://github.com/9flats/nineflats-api-example) app to use the latest one. You need to change the version in the `Gemfile`, and you might to adapt the code, too.
15
+
data/Rakefile CHANGED
@@ -1,5 +1,18 @@
1
+ require 'bundler'
2
+ begin
3
+ Bundler.setup(:default, :development)
4
+ rescue Bundler::BundlerError => e
5
+ $stderr.puts e.message
6
+ $stderr.puts "Run `bundle install` to install missing gems"
7
+ exit e.status_code
8
+ end
9
+
10
+ require 'rake'
1
11
  require "bundler/gem_tasks"
2
- require 'rspec/core/rake_task'
3
12
 
4
- desc "Run all RSpec tests"
5
- RSpec::Core::RakeTask.new(:spec)
13
+ require 'rspec/core'
14
+ require 'rspec/core/rake_task'
15
+ RSpec::Core::RakeTask.new(:spec) do |spec|
16
+ spec.pattern = FileList['spec/**/*_spec.rb']
17
+ end
18
+ task :default => 'spec'
@@ -9,11 +9,17 @@ module Nineflats
9
9
  end
10
10
 
11
11
  def self.base_url
12
- "http://api.9flats.com/api"
12
+ "http://api.9flats.com/api/v1"
13
13
  end
14
14
 
15
15
  def self.api_call
16
16
  raise "override me!"
17
17
  end
18
+
19
+ def self.object_link(name, array)
20
+ link = array.select{ |link|
21
+ link["rel"] == name
22
+ }.first["href"]
23
+ end
18
24
  end
19
25
  end
@@ -0,0 +1,17 @@
1
+ module Nineflats
2
+ class Calendar < Base
3
+ attr_accessor :year, :month, :days
4
+
5
+ def initialize(json)
6
+ calendar = json.first[1]
7
+
8
+ @year = calendar["year"]
9
+ @month = calendar["month"]
10
+ @days = calendar["days"]
11
+ end
12
+
13
+ def self.api_call(slug, year, month)
14
+ base_url + "/places/#{slug}/calendar/#{year}/#{month}?client_id=#{Nineflats::Base.client_app_key}"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,10 @@
1
+ module Nineflats
2
+ class PaginatedArray < Array
3
+ attr_accessor :total_entries, :total_pages, :current_page, :per_page,
4
+ :self_url, :full_url, :next_page_url
5
+
6
+ def next_page
7
+ Place.search_result(next_page_url)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ module Nineflats
2
+ class Photo < Base
3
+ attr_accessor :title, :caption, :url
4
+
5
+ def initialize(json)
6
+ photo = json.first[1]
7
+
8
+ @title = photo["title"]
9
+ @caption = photo["caption"]
10
+ @url = photo["url"]
11
+ end
12
+
13
+ def self.api_call(slug)
14
+ base_url + "/places/#{slug}/photos?client_id=#{Nineflats::Base.client_app_key}"
15
+ end
16
+ end
17
+ end
@@ -6,8 +6,10 @@ module Nineflats
6
6
  :size, :house_rules, :pets_around, :bathroom_type, :cleaning_fee,
7
7
  :charge_per_extra_person_limit, :favorites_count, :amenities_list,
8
8
  :featured_photo_url, :price, :charge_per_extra_person, :country,
9
- :category, :place_type, :bed_type, :bathroom_type,
10
- :host, :self_url, :full_url, :prices
9
+ :category, :place_type, :bed_type, :bathroom_type, :description,
10
+ :host, :self_url, :full_url, :photos_url, :prices_url, :reviews_url,
11
+ :calendar_current_month_url, :calendar_next_month_url,
12
+ :prices, :reviews, :photos
11
13
 
12
14
  def initialize(json)
13
15
  place = json.first[1]
@@ -41,11 +43,49 @@ module Nineflats
41
43
  @lat = place["lat"]
42
44
  @lng = place["lng"]
43
45
  @district = place["district"]
46
+ @description = place["description"]
44
47
 
45
- @host = User.new({"user"=>place["host"]})
48
+ @host = User.new({"user" => place["host"]})
46
49
 
47
- @self_url = place["links"].first.select{|link| link["rel"] == "self"}["href"]
48
- @full_url = place["links"].first.select{|link| link["rel"] == "full"}["href"]
50
+ @self_url = Nineflats::Base.object_link("self", place["links"])
51
+ @full_url = Nineflats::Base.object_link("full", place["links"])
52
+ @photos_url = Nineflats::Base.object_link("photos", place["links"])
53
+ @prices_url = Nineflats::Base.object_link("prices", place["links"])
54
+ @reviews_url = Nineflats::Base.object_link("reviews", place["links"])
55
+ @calendar_current_month_url = Nineflats::Base.object_link("calendar: current month", place["links"])
56
+ @calendar_next_month_url = Nineflats::Base.object_link("calendar: next month", place["links"])
57
+ end
58
+
59
+ def self.search(params = nil)
60
+ params ||= {}
61
+
62
+ queries = params.collect do |key, value|
63
+ "&search[#{key}]=#{value}"
64
+ end
65
+
66
+ search_url = base_url + "/places?client_id=#{Nineflats::Base.client_app_key}" + queries.join
67
+
68
+ Place.search_result(search_url)
69
+ end
70
+
71
+ def self.search_result(search_url)
72
+ json = Helpers.get_data(search_url)
73
+
74
+ places = json["places"].collect do |place_json|
75
+ Place.new(place_json)
76
+ end
77
+
78
+ result = Nineflats::PaginatedArray.new(places)
79
+
80
+ result.total_entries = json["total_entries"]
81
+ result.total_pages = json["total_pages"]
82
+ result.current_page = json["current_page"]
83
+ result.per_page = json["per_page"]
84
+
85
+ result.self_url = Nineflats::Base.object_link("self", json["links"])
86
+ result.full_url = Nineflats::Base.object_link("full", json["links"])
87
+ result.next_page_url = Nineflats::Base.object_link("next_page", json["links"])
88
+ result
49
89
  end
50
90
 
51
91
  def self.fetch(slug, lang)
@@ -53,11 +93,45 @@ module Nineflats
53
93
  end
54
94
 
55
95
  def prices
56
- @prices = Prices.new(Helpers.get_data(Prices.api_call(slug)))
96
+ return @prices if @prices
97
+
98
+ json = Helpers.get_data(Prices.api_call(slug))
99
+
100
+ @prices = Prices.new(json) if json && json["place_prices"]
101
+ end
102
+
103
+ def reviews
104
+ return @reviews if @reviews
105
+
106
+ json = Helpers.get_data(Review.api_call(slug))
107
+
108
+ if json && json["reviews"]
109
+ @reviews = json["reviews"].collect do |review_hash|
110
+ Review.new(review_hash)
111
+ end
112
+ end
113
+ end
114
+
115
+ def photos
116
+ return @photos if @photos
117
+
118
+ json = Helpers.get_data(Photo.api_call(slug))
119
+
120
+ if json && json["place_photos"]
121
+ @photos = json["place_photos"].collect do |photo_hash|
122
+ Photo.new(photo_hash)
123
+ end
124
+ end
125
+ end
126
+
127
+ def calendar(year, month)
128
+ json = Helpers.get_data(Calendar.api_call(slug, year, month))
129
+
130
+ Calendar.new(json) if json && json["calendar"]
57
131
  end
58
132
 
59
133
  def self.api_call(slug, lang)
60
- base_url + "/places/#{slug}.json?client_id=#{Nineflats::Base.client_app_key}&language=#{lang}"
134
+ base_url + "/places/#{slug}?client_id=#{Nineflats::Base.client_app_key}&lang=#{lang}"
61
135
  end
62
136
  end
63
137
  end
@@ -13,14 +13,13 @@ module Nineflats
13
13
  @weekly_discount_in_percent = prices["weekly_discount_in_percent"]
14
14
  @monthly_discount_in_percent = prices["monthly_discount_in_percent"]
15
15
 
16
- @seasons = []
17
- prices["seasons"].each do |season|
18
- @seasons << Season.new(season)
16
+ @seasons = prices["seasons"].collect do |season|
17
+ Season.new(season)
19
18
  end
20
19
  end
21
20
 
22
21
  def self.api_call(slug)
23
- base_url + "/places/#{slug}/prices.json?client_id=#{Nineflats::Base.client_app_key}"
22
+ base_url + "/places/#{slug}/prices?client_id=#{Nineflats::Base.client_app_key}"
24
23
  end
25
24
  end
26
25
  end
@@ -0,0 +1,18 @@
1
+ module Nineflats
2
+ class Review < Base
3
+ attr_accessor :user_text, :place_text, :place_stars, :language
4
+
5
+ def initialize(json)
6
+ review = json.first[1]
7
+
8
+ @user_text = review["user_text"]
9
+ @place_text = review["place_text"]
10
+ @place_stars = review["place_stars"]
11
+ @language = review["language"]
12
+ end
13
+
14
+ def self.api_call(slug)
15
+ base_url + "/places/#{slug}/reviews?client_id=#{Nineflats::Base.client_app_key}"
16
+ end
17
+ end
18
+ end
@@ -1,6 +1,7 @@
1
1
  module Nineflats
2
2
  class User < Base
3
- attr_accessor :name, :slug, :user_photo_url, :self_url, :favorites_url
3
+ attr_accessor :name, :slug, :user_photo_url, :favorites,
4
+ :self_url, :favorites_url, :full_url
4
5
 
5
6
  def initialize(json)
6
7
  user = json.first[1]
@@ -10,17 +11,30 @@ module Nineflats
10
11
  @user_photo_url = user["user_photo_url"]
11
12
 
12
13
  if user["links"]
13
- @self_url = user["links"].first.select{|link| link["rel"] == "self"}["href"]
14
- @favorites_url = user["links"].first.select{|link| link["rel"] == "favorites"}["href"]
14
+ @self_url = Nineflats::Base.object_link("self", user["links"])
15
+ @full_url = Nineflats::Base.object_link("full", user["links"])
16
+ @favorites_url = Nineflats::Base.object_link("favorites", user["links"])
17
+ end
18
+ end
19
+
20
+ def favorites
21
+ return @favorites if @favorites
22
+
23
+ json = Helpers.get_data(favorites_url)
24
+
25
+ if json && json["places"]
26
+ @favorites = json["places"].collect do |place_hash|
27
+ Place.new(place_hash)
28
+ end
15
29
  end
16
30
  end
17
31
 
18
- def self.fetch(slug, lang)
19
- User.new(Helpers.get_data(User.api_call(slug, lang)))
32
+ def self.fetch(slug)
33
+ User.new(Helpers.get_data(User.api_call(slug)))
20
34
  end
21
-
22
- def self.api_call(slug, lang)
23
- base_url + "/users/#{slug}.json?client_id=#{Nineflats::Base.client_app_key}&language=#{lang}"
35
+
36
+ def self.api_call(slug)
37
+ base_url + "/users/#{slug}?client_id=#{Nineflats::Base.client_app_key}"
24
38
  end
25
39
  end
26
40
  end
@@ -1,5 +1,5 @@
1
1
  module Nineflats
2
2
  module Api
3
- VERSION = "0.0.3"
3
+ VERSION = "0.0.4"
4
4
  end
5
5
  end
@@ -11,10 +11,13 @@ Gem::Specification.new do |s|
11
11
  s.summary = %q{9flats API}
12
12
  s.description = %q{Let's you use the 9flats API'}
13
13
 
14
- s.rubyforge_project = "nineflats-api"
15
-
16
14
  s.files = `git ls-files`.split("\n")
17
15
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
16
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+
19
18
  s.require_paths = ["lib"]
19
+
20
+ s.add_development_dependency('rake', '~> 0.9.0')
21
+ s.add_development_dependency('rspec')
22
+ s.add_development_dependency('fakeweb')
20
23
  end
@@ -0,0 +1,66 @@
1
+ {
2
+ "place": {
3
+ "name": "Great river view, Colorful and Cozy",
4
+ "city": "Lisboa",
5
+ "slug": "apt-no-centro-histrico-de-lisboa",
6
+ "zipcode": "1100-188",
7
+ "number_of_beds": 4,
8
+ "number_of_bedrooms": 1,
9
+ "currency": "EUR",
10
+ "lat": 38.7173993,
11
+ "lng": -9.1204621,
12
+ "district": "",
13
+ "number_of_bathrooms": 1,
14
+ "minimum_nights": 2,
15
+ "maximum_nights": 365,
16
+ "bed_type": "Real bed",
17
+ "size": 70.0,
18
+ "house_rules": "",
19
+ "pets_around": false,
20
+ "bathroom_type": "Private",
21
+ "cleaning_fee": null,
22
+ "charge_per_extra_person_limit": 4,
23
+ "favorites_count": 5,
24
+ "amenities_list": ["Internet", "Wifi (Wireless LAN)", "TV", "Air Conditioning", "Kitchen", "Washer", "Smoking allowed", "Family/Kid friendly", "Pets allowed", "Balcony", "Dishwasher", "Fridge/freezer", "Shower/bathtub", "Baby crib", "Final cleaning", "Panoramic view", "Gay friendly"],
25
+ "featured_photo_url": "http://img1.9flats.com/place_photos/photos/62387-1311446301/medium.jpg",
26
+ "description": "Panoramic terrace in the historic center of Lisbon, close to Subway and Airport",
27
+ "price": 90.0,
28
+ "charge_per_extra_person": 20.0,
29
+ "content_language": "en",
30
+ "country": "Portugal",
31
+ "category": "Apartment",
32
+ "place_type": "Entire place",
33
+ "links": [{
34
+ "rel": "self",
35
+ "href": "http://api.9flats.com/api/v1/places/apt-no-centro-histrico-de-lisboa?client_id=WfKWrPywnEbMhlifGlrsLu2ULfvTwxrKQji5eg0S"
36
+ },
37
+ {
38
+ "rel": "full",
39
+ "href": "http://www.9flats.com/places/apt-no-centro-histrico-de-lisboa"
40
+ },
41
+ {
42
+ "rel": "photos",
43
+ "href": "http://api.9flats.com/api/v1/places/apt-no-centro-histrico-de-lisboa/photos?client_id=WfKWrPywnEbMhlifGlrsLu2ULfvTwxrKQji5eg0S"
44
+ },
45
+ {
46
+ "rel": "prices",
47
+ "href": "http://api.9flats.com/api/v1/places/apt-no-centro-histrico-de-lisboa/prices?client_id=WfKWrPywnEbMhlifGlrsLu2ULfvTwxrKQji5eg0S"
48
+ },
49
+ {
50
+ "rel": "reviews",
51
+ "href": "http://api.9flats.com/api/v1/places/apt-no-centro-histrico-de-lisboa/reviews?client_id=WfKWrPywnEbMhlifGlrsLu2ULfvTwxrKQji5eg0S"
52
+ },
53
+ {
54
+ "rel": "calendar: current month",
55
+ "href": "http://api.9flats.com/api/v1/places/apt-no-centro-histrico-de-lisboa/calendar/2011/10?client_id=WfKWrPywnEbMhlifGlrsLu2ULfvTwxrKQji5eg0S"
56
+ },
57
+ {
58
+ "rel": "calendar: next month",
59
+ "href": "http://api.9flats.com/api/v1/places/apt-no-centro-histrico-de-lisboa/calendar/2011/11?client_id=WfKWrPywnEbMhlifGlrsLu2ULfvTwxrKQji5eg0S"
60
+ }],
61
+ "host": {
62
+ "name": "Paulo M.",
63
+ "slug": "paulo-m"
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,47 @@
1
+ {
2
+ "calendar": {
3
+ "year": 2011,
4
+ "month": 10,
5
+ "days": {
6
+ "1": true,
7
+ "2": true,
8
+ "3": true,
9
+ "4": true,
10
+ "5": false,
11
+ "6": false,
12
+ "7": false,
13
+ "8": false,
14
+ "9": true,
15
+ "10": false,
16
+ "11": true,
17
+ "12": true,
18
+ "13": true,
19
+ "14": true,
20
+ "15": true,
21
+ "16": true,
22
+ "17": true,
23
+ "18": true,
24
+ "19": true,
25
+ "20": false,
26
+ "21": false,
27
+ "22": false,
28
+ "23": true,
29
+ "24": false,
30
+ "25": true,
31
+ "26": true,
32
+ "27": true,
33
+ "28": true,
34
+ "29": true,
35
+ "30": true,
36
+ "31": false
37
+ }
38
+ },
39
+ "links": [{
40
+ "rel": "self",
41
+ "href": "http://www.9flats.com/api/v1/places/harmony-villas-close-to-the-sea/calendar/2011/10?client_id=WfKWrPywnEbMhlifGlrsLu2ULfvTwxrKQji5eg0S"
42
+ },
43
+ {
44
+ "rel": "calendar: next month",
45
+ "href": "http://www.9flats.com/api/v1/places/harmony-villas-close-to-the-sea/calendar/2011/11?client_id=WfKWrPywnEbMhlifGlrsLu2ULfvTwxrKQji5eg0S"
46
+ }]
47
+ }
@@ -0,0 +1,163 @@
1
+ {
2
+ "place_photos": [
3
+ {
4
+ "place_photo": {
5
+ "title": "Terrace with National Pantheon view",
6
+ "caption": null,
7
+ "url": "http://img2.9flats.com/place_photos/photos/62387-1311446301/large.jpg"
8
+ }
9
+ },
10
+ {
11
+ "place_photo": {
12
+ "title": "Terrace with river Tagus view",
13
+ "caption": null,
14
+ "url": "http://img3.9flats.com/place_photos/photos/62388-1311446306/large.jpg"
15
+ }
16
+ },
17
+ {
18
+ "place_photo": {
19
+ "title": "Family room with removable dining table",
20
+ "caption": null,
21
+ "url": "http://img3.9flats.com/place_photos/photos/62389-1311446311/large.jpg"
22
+ }
23
+ },
24
+ {
25
+ "place_photo": {
26
+ "title": "Family room with river view",
27
+ "caption": null,
28
+ "url": "http://img0.9flats.com/place_photos/photos/62390-1311446315/large.jpg"
29
+ }
30
+ },
31
+ {
32
+ "place_photo": {
33
+ "title": "Double room with river view",
34
+ "caption": null,
35
+ "url": "http://img2.9flats.com/place_photos/photos/62391-1311446320/large.jpg"
36
+ }
37
+ },
38
+ {
39
+ "place_photo": {
40
+ "title": "Double room with big wardrobes",
41
+ "caption": null,
42
+ "url": "http://img1.9flats.com/place_photos/photos/62392-1311446325/large.jpg"
43
+ }
44
+ },
45
+ {
46
+ "place_photo": {
47
+ "title": "Kitchen with fridge freezer",
48
+ "caption": null,
49
+ "url": "http://img2.9flats.com/place_photos/photos/62393-1311446330/large.jpg"
50
+ }
51
+ },
52
+ {
53
+ "place_photo": {
54
+ "title": "Kitchen fully equipped",
55
+ "caption": null,
56
+ "url": "http://img0.9flats.com/place_photos/photos/62394-1311446334/large.jpg"
57
+ }
58
+ },
59
+ {
60
+ "place_photo": {
61
+ "title": "Bathroom",
62
+ "caption": null,
63
+ "url": "http://img1.9flats.com/place_photos/photos/62395-1311446339/large.jpg"
64
+ }
65
+ },
66
+ {
67
+ "place_photo": {
68
+ "title": "Family room with French doors",
69
+ "caption": null,
70
+ "url": "http://img1.9flats.com/place_photos/photos/62396-1311446344/large.jpg"
71
+ }
72
+ },
73
+ {
74
+ "place_photo": {
75
+ "title": "Terrace with National Pantheon view",
76
+ "caption": null,
77
+ "url": "http://img1.9flats.com/place_photos/photos/62397-1311446348/large.jpg"
78
+ }
79
+ },
80
+ {
81
+ "place_photo": {
82
+ "title": "Terrace with panoramic view",
83
+ "caption": null,
84
+ "url": "http://img3.9flats.com/place_photos/photos/62398-1311446353/large.jpg"
85
+ }
86
+ },
87
+ {
88
+ "place_photo": {
89
+ "title": "Night view",
90
+ "caption": null,
91
+ "url": "http://img3.9flats.com/place_photos/photos/62399-1311446357/large.jpg"
92
+ }
93
+ },
94
+ {
95
+ "place_photo": {
96
+ "title": "Cruise at night view",
97
+ "caption": null,
98
+ "url": "http://img0.9flats.com/place_photos/photos/62400-1311446362/large.jpg"
99
+ }
100
+ },
101
+ {
102
+ "place_photo": {
103
+ "title": "Double room with full mirror",
104
+ "caption": null,
105
+ "url": "http://img0.9flats.com/place_photos/photos/62401-1311446366/large.jpg"
106
+ }
107
+ },
108
+ {
109
+ "place_photo": {
110
+ "title": "Hall",
111
+ "caption": null,
112
+ "url": "http://img3.9flats.com/place_photos/photos/62402-1311446371/large.jpg"
113
+ }
114
+ },
115
+ {
116
+ "place_photo": {
117
+ "title": "Family room with TV, DVD and Stereo",
118
+ "caption": null,
119
+ "url": "http://img1.9flats.com/place_photos/photos/62403-1311446376/large.jpg"
120
+ }
121
+ },
122
+ {
123
+ "place_photo": {
124
+ "title": "Family room with sofa bed",
125
+ "caption": null,
126
+ "url": "http://img2.9flats.com/place_photos/photos/62404-1311446380/large.jpg"
127
+ }
128
+ },
129
+ {
130
+ "place_photo": {
131
+ "title": "Double room with French doors",
132
+ "caption": null,
133
+ "url": "http://img2.9flats.com/place_photos/photos/62405-1311446385/large.jpg"
134
+ }
135
+ },
136
+ {
137
+ "place_photo": {
138
+ "title": "Double room with terrace access",
139
+ "caption": null,
140
+ "url": "http://img3.9flats.com/place_photos/photos/62406-1311446389/large.jpg"
141
+ }
142
+ },
143
+ {
144
+ "place_photo": {
145
+ "title": "Terrace with river Tagus view",
146
+ "caption": null,
147
+ "url": "http://img2.9flats.com/place_photos/photos/62407-1311446394/large.jpg"
148
+ }
149
+ },
150
+ {
151
+ "place_photo": {
152
+ "title": "Terrace with river Tagus view",
153
+ "caption": null,
154
+ "url": "http://img0.9flats.com/place_photos/photos/62408-1311446399/large.jpg"
155
+ }
156
+ }
157
+ ],
158
+ "total_entries": 22,
159
+ "links": [{
160
+ "rel": "self",
161
+ "href": "http://api.9flats.com/api/v1/places/harmony-villas-close-to-the-sea/photos?client_id=WfKWrPywnEbMhlifGlrsLu2ULfvTwxrKQji5eg0S"
162
+ }]
163
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "place_prices": {
3
+ "currency": "EUR",
4
+ "default_price": 90.0,
5
+ "weekend_night_price": 90.0,
6
+ "weekly_discount_in_percent": 5.55,
7
+ "monthly_discount_in_percent": 11.11,
8
+ "seasons": [{
9
+ "season": {
10
+ "from": "2011-09-05",
11
+ "to": "2011-09-30",
12
+ "price": 100.0,
13
+ "weekend_night_price": 110.0
14
+ }
15
+ },
16
+ {
17
+ "season": {
18
+ "from": "2011-10-01",
19
+ "to": "2011-10-31",
20
+ "price": 75.0,
21
+ "weekend_night_price": 75.0
22
+ }
23
+ }]
24
+ },
25
+ "links": [{
26
+ "rel": "self",
27
+ "href": "http://api.9flats.com/api/v1/places/harmony-villas-close-to-the-sea/prices?client_id=WfKWrPywnEbMhlifGlrsLu2ULfvTwxrKQji5eg0S"
28
+ }]
29
+ }