beds24 0.1.0 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d3b02a8362581d3ebed53d6b8435412849e83446cf143fbaabea7a253093422c
4
- data.tar.gz: e5e5db7df54d9440f872b53ccd88d70ed1eeac63134bf2f819918572ca5a6a3f
3
+ metadata.gz: 516840b24ce1a38cef9407d190397c3a44c6c089b3d39e951a452325f9a46b93
4
+ data.tar.gz: e72470ca5cf482c9acede7e5b4f641c060004f7c567606460a85937e6f56d08c
5
5
  SHA512:
6
- metadata.gz: 6a812f642b4b28d79711f812d4a9a6f237aca7a97bbb113b0dfdfc73b6e722a240d4099c5831a3cf0034cd92652d3ca5af720b5aaff8366a25680f2b09f1d3a3
7
- data.tar.gz: 463ab8caa7c300ec0975e3176e7171dbbb5d5315389643c915859ae48e1d30befac11ae1e8657cf492f7297874c3e6e0220cd0824141e7c8ca6d146f54298495
6
+ metadata.gz: 5ea509efe8a7496f581fcecce0cb1bd295715389ff593bc0a1c40459b56180837c18fe10d547bc4833266753299553106ee0b14d6db7a9d04d5e94a14229e23e
7
+ data.tar.gz: 42f9b60e574ad2541c020fe94c2dc605198678ae5105c7c06e13774e6b3a133a2c08559ef1d41de1aaf57ec7036c3de8c7754aa0589f2e56331916879519c195
@@ -0,0 +1,33 @@
1
+ example_id | status | run_time |
2
+ -------------------------------------- | ------ | --------------- |
3
+ ./spec/beds24_spec.rb[1:1] | passed | 0.00159 seconds |
4
+ ./spec/hash_spec.rb[1:1:1] | passed | 0.00247 seconds |
5
+ ./spec/hash_spec.rb[1:1:2] | passed | 0.00467 seconds |
6
+ ./spec/hash_spec.rb[1:1:3] | passed | 0.01313 seconds |
7
+ ./spec/hash_spec.rb[1:1:4] | passed | 0.00266 seconds |
8
+ ./spec/hash_spec.rb[1:1:5] | passed | 0.00146 seconds |
9
+ ./spec/hash_spec.rb[1:1:6] | passed | 0.00117 seconds |
10
+ ./spec/json_client_spec.rb[1:1:1] | passed | 0.00014 seconds |
11
+ ./spec/json_client_spec.rb[1:2:1] | passed | 0.00052 seconds |
12
+ ./spec/json_client_spec.rb[1:2:2] | passed | 0.00011 seconds |
13
+ ./spec/json_client_spec.rb[1:3:1:1] | passed | 0.01676 seconds |
14
+ ./spec/json_client_spec.rb[1:3:2:1] | passed | 0.00161 seconds |
15
+ ./spec/json_client_spec.rb[1:4:1:1] | passed | 0.00227 seconds |
16
+ ./spec/json_client_spec.rb[1:4:2:1] | passed | 0.00131 seconds |
17
+ ./spec/json_client_spec.rb[1:5:1:1] | passed | 0.00297 seconds |
18
+ ./spec/json_client_spec.rb[1:5:2:1] | passed | 0.00236 seconds |
19
+ ./spec/xml_client_spec.rb[1:1:1] | passed | 0.00032 seconds |
20
+ ./spec/xml_client_spec.rb[1:2:1:1] | passed | 0.00054 seconds |
21
+ ./spec/xml_client_spec.rb[1:2:1:2] | passed | 0.00044 seconds |
22
+ ./spec/xml_client_spec.rb[1:2:2:1] | passed | 0.00033 seconds |
23
+ ./spec/xml_client_spec.rb[1:2:2:2] | passed | 0.00028 seconds |
24
+ ./spec/xml_client_spec.rb[1:3:1:1:1:1] | passed | 0.00589 seconds |
25
+ ./spec/xml_client_spec.rb[1:3:1:2:1] | passed | 0.00557 seconds |
26
+ ./spec/xml_client_spec.rb[1:3:2:1:1:1] | passed | 0.00727 seconds |
27
+ ./spec/xml_client_spec.rb[1:3:2:2:1] | passed | 0.00511 seconds |
28
+ ./spec/xml_client_spec.rb[1:3:3:1:1:1] | passed | 0.00455 seconds |
29
+ ./spec/xml_client_spec.rb[1:3:3:2:1] | passed | 0.00421 seconds |
30
+ ./spec/xml_request_spec.rb[1:1:1] | passed | 0.00083 seconds |
31
+ ./spec/xml_request_spec.rb[1:1:2] | passed | 0.00083 seconds |
32
+ ./spec/xml_request_spec.rb[1:2:1] | passed | 0.00067 seconds |
33
+ ./spec/xml_request_spec.rb[1:2:2] | passed | 0.00064 seconds |
@@ -0,0 +1,22 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2019-10-11
11
+
12
+ ### Added
13
+
14
+ - Added ability to list properties in JSON format
15
+ - Added XML client to interact with XML API
16
+ - Added ability to fetch properties through XML API
17
+ - Added ability to fetch bookings through XML API
18
+ - Added ability to show bookings for a property
19
+
20
+ ### Changed
21
+
22
+ ### Removed
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Beds24 [![Build Status](https://travis-ci.com/mihilbabin/booking_automation.svg?branch=master)](https://travis-ci.com/mihilbabin/booking_automation) [![Gem Version](https://badge.fury.io/rb/booking_automation.svg)](https://badge.fury.io/rb/booking_automation)
1
+ # Beds24 [![Build Status](https://travis-ci.org/mihilbabin/beds24.svg?branch=master)](https://travis-ci.org/mihilbabin/beds24) [![Gem Version](https://badge.fury.io/rb/beds24.svg)](https://badge.fury.io/rb/beds24)
2
2
 
3
3
  This is a simple wrapper of [Beds24 API](https://beds24.com/api/index.html). It allows to fetch data related to properties and bookings created and filter that data as per API docs.
4
4
 
@@ -1,6 +1,23 @@
1
- require "beds24/version"
1
+ require 'httparty'
2
+ require 'oj'
3
+
4
+ require 'beds24/constants'
5
+ require 'beds24/json_client'
6
+ require 'beds24/version'
7
+ require 'beds24/xml_client'
8
+ require 'beds24/xml_request'
9
+
10
+ require 'ext/hash'
2
11
 
3
12
  module Beds24
4
13
  class Error < StandardError; end
5
- # Your code goes here...
14
+
15
+ class APIError < StandardError
16
+ attr_accessor :response
17
+
18
+ def initialize(msg, response)
19
+ super(msg)
20
+ @response = response
21
+ end
22
+ end
6
23
  end
@@ -0,0 +1,30 @@
1
+ module Beds24
2
+ module Constants
3
+ API_ROOT = 'https://beds24.com/api'.freeze
4
+ JSON_API_ENDPOINT = "#{API_ROOT}/json".freeze
5
+ XML_API_ENDPOINT = "#{API_ROOT}/xml".freeze
6
+
7
+ PARSE_ERROR_MSG = 'Got encoding different from JSON. Please check passed options'.freeze
8
+
9
+ DEFAULT_PROPERTY_OPTIONS = {
10
+ includeRooms: false,
11
+ includeRoomUnits: false,
12
+ includeAccountAccess: false
13
+ }.freeze
14
+
15
+ DEFAULT_BOOKING_OPTIONS = {
16
+ includeInvoice: false,
17
+ includeInfoItems: false
18
+ }.freeze
19
+
20
+ VALID_XML_BOOKING_OPTS = %i[
21
+ modified
22
+ datefrom
23
+ dateto
24
+ propid
25
+ roomid
26
+ masterid
27
+ bookid
28
+ ].freeze
29
+ end
30
+ end
@@ -0,0 +1,73 @@
1
+ module Beds24
2
+ class JSONClient
3
+ include HTTParty
4
+ base_uri Constants::JSON_API_ENDPOINT
5
+
6
+ attr_accessor :auth_token
7
+
8
+ def initialize(auth_token)
9
+ @auth_token = auth_token
10
+ end
11
+
12
+ def get_properties
13
+ response = self.class.post('/getProperties', body: authentication.to_json)
14
+ json = parse! response
15
+ json['getProperties']
16
+ rescue Oj::ParseError
17
+ raise Error, Constants::PARSE_ERROR_MSG
18
+ rescue APIError => e
19
+ e.response
20
+ end
21
+
22
+ def get_property(prop_key, options={})
23
+ response = self.class.post(
24
+ '/getProperty',
25
+ body: payload(prop_key, Constants::DEFAULT_PROPERTY_OPTIONS.merge(options))
26
+ )
27
+ json = parse! response
28
+ json['getProperty'].first
29
+ rescue Oj::ParseError
30
+ raise Error, Constants::PARSE_ERROR_MSG
31
+ rescue APIError => e
32
+ e.response
33
+ end
34
+
35
+ def get_bookings(prop_key, options={})
36
+ response = self.class.post(
37
+ '/getBookings',
38
+ body: payload(prop_key, Constants::DEFAULT_BOOKING_OPTIONS.merge(options))
39
+ )
40
+ parse! response
41
+ rescue Oj::ParseError
42
+ raise Error, Constants::PARSE_ERROR_MSG
43
+ rescue APIError => e
44
+ e.response
45
+ end
46
+
47
+ private
48
+
49
+ def authentication(prop_key=nil)
50
+ {
51
+ authentication: {
52
+ apiKey: auth_token,
53
+ propKey: prop_key
54
+ }
55
+ }
56
+ end
57
+
58
+ def payload(prop_key=nil, options={})
59
+ authentication(prop_key)
60
+ .merge(options)
61
+ .to_json
62
+ end
63
+
64
+ def parse!(response)
65
+ json = Oj.load response.body
66
+ raise APIError.new(
67
+ "API Error: #{json['errorCode']} #{json['error']}",
68
+ json
69
+ ) if json.is_a?(Hash) && !json['error'].nil?
70
+ json
71
+ end
72
+ end
73
+ end
@@ -1,3 +1,3 @@
1
1
  module Beds24
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -0,0 +1,68 @@
1
+ module Beds24
2
+ class XMLClient
3
+ include HTTParty
4
+ base_uri Constants::XML_API_ENDPOINT
5
+ headers 'Content-Type' => 'text/xml'
6
+
7
+ attr_accessor :username, :password
8
+
9
+ def initialize(username, password)
10
+ @username = username
11
+ @password = password
12
+ end
13
+
14
+ def get_properties(opts = {})
15
+ response = self.class.post('/getProperties', body: xmlize(opts.slice(:propid)))
16
+ parse! response
17
+ rescue APIError => e
18
+ e.response
19
+ end
20
+
21
+ def get_bookings(opts = {})
22
+ valid_opts = opts.slice(*Constants::VALID_XML_BOOKING_OPTS)
23
+ response = self.class.post('/getBookings', body: xmlize(valid_opts))
24
+ parse! response
25
+ rescue APIError => e
26
+ e.response
27
+ end
28
+
29
+ def modify_booking(id, attrs = {})
30
+ response = self.class.post('/putBookings', body: modify_payload(id, attrs))
31
+ parse! response
32
+ rescue APIError => e
33
+ e.response
34
+ end
35
+
36
+ private
37
+
38
+ def parse!(response)
39
+ hash = Hash.from_xml(response.body)
40
+ raise APIError.new(
41
+ "API Error: #{hash['code']} #{hash['error']}",
42
+ hash
43
+ ) if hash.key?('error')
44
+ hash
45
+ end
46
+
47
+ def auth
48
+ { username: @username, password: @password }
49
+ end
50
+
51
+ def xmlize(opts = {})
52
+ XMLRequest.new(auth, opts).to_xml
53
+ end
54
+
55
+ def modify_payload(id, attrs = {})
56
+ payload = Nokogiri::XML(xmlize())
57
+ Nokogiri::XML::Builder.with(payload.at('request')) do |xml|
58
+ xml.bookings do
59
+ xml.booking(id: id, action: 'modify') do
60
+ attrs.each do |prop, value|
61
+ xml.public_send prop, value
62
+ end
63
+ end
64
+ end
65
+ end.doc.root.to_xml
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,29 @@
1
+ module Beds24
2
+ class XMLRequest
3
+ def initialize(auth, opts = {})
4
+ @auth = auth
5
+ @opts = opts
6
+ end
7
+
8
+ def to_xml
9
+ data = builder.new do |xml|
10
+ xml.request do
11
+ xml.auth do
12
+ xml.username @auth[:username]
13
+ xml.password @auth[:password]
14
+ end
15
+ @opts.each do |prop, value|
16
+ xml.public_send prop, value
17
+ end
18
+ end
19
+ end
20
+ data.doc.root.to_xml
21
+ end
22
+
23
+ private
24
+
25
+ def builder
26
+ Nokogiri::XML::Builder
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,56 @@
1
+ require 'nokogiri'
2
+
3
+ class Hash
4
+ class << self
5
+ def from_xml(xml_io)
6
+ result = Nokogiri::XML(xml_io)
7
+ { result.root.name => xml_node_to_hash(result.root)}
8
+ end
9
+
10
+ def xml_node_to_hash(node)
11
+ if node.element?
12
+ result_hash = {}
13
+ if node.attributes != {}
14
+ attributes = {}
15
+ node.attributes.keys.each do |key|
16
+ if [:id, 'id', :name, 'name'].include?(key)
17
+ node.name = node.attributes[key].value
18
+ node.delete(key.to_s)
19
+ else
20
+ attributes[node.attributes[key].name] = node.attributes[key].value
21
+ end
22
+ end
23
+ end
24
+
25
+ if node.children.size > 0
26
+ node.children.each do |child|
27
+ result = xml_node_to_hash(child)
28
+
29
+ if child.name == 'text'
30
+ unless child.next_sibling || child.previous_sibling
31
+ return result unless attributes
32
+ result_hash[child.name] = result
33
+ end
34
+ elsif result_hash[child.name]
35
+ if result_hash[child.name].is_a?(Array)
36
+ result_hash[child.name] << result
37
+ else
38
+ result_hash[child.name] = [result_hash[child.name]] << result
39
+ end
40
+ else
41
+ result_hash[child.name] = result
42
+ end
43
+ end
44
+ if attributes
45
+ result_hash = attributes.merge(result_hash)
46
+ end
47
+ return result_hash
48
+ else
49
+ return attributes
50
+ end
51
+ else
52
+ node.content.to_s
53
+ end
54
+ end
55
+ end
56
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beds24
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Babin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-11 00:00:00.000000000 Z
11
+ date: 2019-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -131,7 +131,9 @@ extra_rdoc_files: []
131
131
  files:
132
132
  - ".gitignore"
133
133
  - ".rspec"
134
+ - ".rspec_status"
134
135
  - ".travis.yml"
136
+ - CHANGELOG.md
135
137
  - Gemfile
136
138
  - LICENSE.txt
137
139
  - README.md
@@ -140,7 +142,12 @@ files:
140
142
  - bin/console
141
143
  - bin/setup
142
144
  - lib/beds24.rb
145
+ - lib/beds24/constants.rb
146
+ - lib/beds24/json_client.rb
143
147
  - lib/beds24/version.rb
148
+ - lib/beds24/xml_client.rb
149
+ - lib/beds24/xml_request.rb
150
+ - lib/ext/hash.rb
144
151
  homepage: https://github.com/mihilbabin/beds24
145
152
  licenses:
146
153
  - MIT