parking_ticket 0.1.2 → 1.0.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 +4 -4
- data/Gemfile.lock +2 -1
- data/README.md +34 -13
- data/lib/client/pay_by_phone/adapter.rb +58 -68
- data/lib/client/pay_by_phone/configuration.rb +9 -0
- data/lib/client/pay_by_phone/request.rb +121 -0
- data/lib/parking_ticket/configuration.rb +26 -0
- data/lib/parking_ticket/version.rb +1 -1
- data/lib/parking_ticket.rb +56 -18
- metadata +5 -5
- data/lib/client/pay_by_phone.rb +0 -113
- data/lib/parking_ticket/ticket.rb +0 -21
- data/parking_ticket.gemspec +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2316d548e3f47bee94290a6e0b4399150d1db6948217c4a0434cae0b3ab5ebd
|
4
|
+
data.tar.gz: 31cbaee19c0e458085ef5ab1c142d2fe5f24a82ff152e9e797c1a8e4ddd03782
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e5c572a25ce7df3ab41f449dbaf1999df4efde403ccad560c87bf284ceb1e08ae3c072a4950a06244ffe94086b147fb0fb56d779a16315cdae05a34e5f39450f
|
7
|
+
data.tar.gz: a1e55ec8f66f0909c49bd53d5cc89ceb243cd6f72d6070befe77f9f57c8b10d4650a396a5f7054cdec7959400e0cb2dd64f42415300bf168f74ebed8715d6e2a
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# ParkingTicket
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
This gem is a wrapper around the majors residential parking tickets api (for now only PayByPhone is supported).
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -22,22 +20,45 @@ Or install it yourself as:
|
|
22
20
|
|
23
21
|
## Usage
|
24
22
|
|
25
|
-
|
23
|
+
To make the gem work above your parking account you need set some environment variables :
|
26
24
|
|
27
|
-
|
25
|
+
#PayByPhone :
|
26
|
+
- `PAYBYPHONE_PASSWORD` : your PayByPhone password
|
27
|
+
- `PAYBYPHONE_USERNAME` : your PayByPhone username (usually your phone number)
|
28
|
+
- `PAYBYPHONE_LICENSEPLATE` : tyhe license plate of the car that must be covered
|
29
|
+
- `PAYBYPHONE_ZIPCODE` : the zipcode you're resident in
|
30
|
+
- `PAYBYPHONE_CARDNUMBER` : the credit card used to pay parking tickets (must be formated as folow xxxxxx------xxxx)
|
28
31
|
|
29
|
-
|
32
|
+
#Other apis to come
|
30
33
|
|
31
|
-
|
34
|
+
Two methods comes with the gem :
|
32
35
|
|
33
|
-
|
36
|
+
#`ParkingTicket.current_ticket`
|
37
|
+
=> returns an object representing a currently running residential ticket for your car. It returns nil if no ticket are found.
|
34
38
|
|
35
|
-
|
39
|
+
#`ParkingTicket.renew`
|
40
|
+
=> register a new residential ticket for your car, this won't work if current_ticket returns something.
|
36
41
|
|
37
|
-
|
42
|
+
Then you can create a scrypt like this one :
|
38
43
|
|
39
|
-
|
44
|
+
```
|
45
|
+
#your_scrypt.rb
|
46
|
+
require 'parking_ticket'
|
40
47
|
|
41
|
-
|
48
|
+
ticket_client = ParkingTicket.new
|
49
|
+
|
50
|
+
unless ticket_client.current_ticket
|
51
|
+
ticket_client.renew
|
52
|
+
end
|
53
|
+
|
54
|
+
```
|
42
55
|
|
43
|
-
|
56
|
+
And play as often as you want to ensure that you always have a ticket for your car.
|
57
|
+
(But this is very HTTP request consuming, a lot of wasted request will be performed, i am sure that you can do better than that.)
|
58
|
+
|
59
|
+
Exemple of application : [parkautomat](https://github.com/troptropcontent/parkautomat)
|
60
|
+
|
61
|
+
|
62
|
+
## License
|
63
|
+
|
64
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -1,71 +1,61 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
1
|
+
module ParkingTicket
|
2
|
+
module Client
|
3
|
+
module PayByPhone
|
4
|
+
class Adapter
|
5
|
+
def initialize(configuration)
|
6
|
+
@configuration = configuration
|
7
|
+
end
|
8
|
+
|
9
|
+
def covered?
|
10
|
+
!!current_ticket
|
11
|
+
end
|
12
|
+
|
13
|
+
def current_ticket
|
14
|
+
ticket = request.tickets(account_id).find do |ticket|
|
15
|
+
ticket.dig('vehicle', 'licensePlate') == @configuration.license_plate
|
16
|
+
end
|
17
|
+
|
18
|
+
return unless ticket
|
19
|
+
|
20
|
+
{
|
21
|
+
starts_on: DateTime.parse(ticket['startTime']),
|
22
|
+
ends_on: DateTime.parse(ticket['expireTime']),
|
23
|
+
license_plate: ticket.dig('vehicle', 'licensePlate'),
|
24
|
+
cost: ticket.dig('segments', 0, 'cost'),
|
25
|
+
client: 'PayByPhone',
|
26
|
+
client_ticket_id: ticket['parkingSessionId']
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def renew
|
31
|
+
return if covered?
|
32
|
+
|
33
|
+
quote = request.new_quote(rate_option_id, account_id)
|
34
|
+
request.new_ticket(account_id, quote['parkingStartTime'], quote['quoteId'], payment_method_id)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def request
|
40
|
+
@request ||= Request.new(@configuration)
|
41
|
+
end
|
42
|
+
|
43
|
+
def account_id
|
44
|
+
@account_id ||= request.accounts.dig(0, 'id')
|
45
|
+
end
|
46
|
+
|
47
|
+
def payment_method_id
|
48
|
+
request.payment_methods['items'].find do |payment_method|
|
49
|
+
payment_method['maskedCardNumber'] == @configuration.card_number
|
50
|
+
end['id']
|
51
|
+
end
|
52
|
+
|
53
|
+
def rate_option_id
|
54
|
+
request.rate_options(account_id).find do |rate_option|
|
55
|
+
rate_option['type'] == 'RES' && rate_option['licensePlate'] == @configuration.license_plate
|
56
|
+
end['rateOptionId']
|
57
|
+
end
|
58
|
+
end
|
17
59
|
end
|
18
|
-
return unless ticket
|
19
|
-
|
20
|
-
{
|
21
|
-
starts_on: DateTime.parse(ticket['startTime']),
|
22
|
-
ends_on: DateTime.parse(ticket['expireTime']),
|
23
|
-
license_plate: ticket.dig('vehicle', 'licensePlate'),
|
24
|
-
cost: ticket.dig('segments', 0, 'cost'),
|
25
|
-
client: 'PayByPhone',
|
26
|
-
client_ticket_id: ticket['parkingSessionId']
|
27
|
-
}
|
28
|
-
end
|
29
|
-
|
30
|
-
def renew
|
31
|
-
return if covered?
|
32
|
-
|
33
|
-
quote = client.new_quote(rate_option_id, account_id)
|
34
|
-
puts client.new_ticket(account_id, quote['parkingStartTime'], quote['quoteId'], payment_method_id)
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def client
|
40
|
-
@client ||= PayByPhone.new
|
41
|
-
end
|
42
|
-
|
43
|
-
def account_id
|
44
|
-
@account_id ||= client.accounts.dig(0, 'id')
|
45
|
-
end
|
46
|
-
|
47
|
-
def payment_method_id
|
48
|
-
client.payment_methods['items'].find do |payment_method|
|
49
|
-
payment_method['maskedCardNumber'] == ENV['PAYBYPHONE_CARDNUMBER']
|
50
|
-
end['id']
|
51
|
-
end
|
52
|
-
|
53
|
-
def rate_option_id
|
54
|
-
client.rate_options(account_id).find do |rate_option|
|
55
|
-
rate_option['type'] == 'RES' && rate_option['licensePlate'] == ENV['PAYBYPHONE_LICENSEPLATE']
|
56
|
-
end['rateOptionId']
|
57
|
-
end
|
58
|
-
|
59
|
-
def check_required_configuarion!
|
60
|
-
return if %w[
|
61
|
-
PAYBYPHONE_PASSWORD
|
62
|
-
PAYBYPHONE_USERNAME
|
63
|
-
PAYBYPHONE_LICENSEPLATE
|
64
|
-
PAYBYPHONE_ZIPCODE
|
65
|
-
PAYBYPHONE_CARDNUMBER
|
66
|
-
].all? { |required_environement_variable| ENV[required_environement_variable] }
|
67
|
-
|
68
|
-
raise Error,
|
69
|
-
'The required configuation are not set properly, the following environnment variable must be set : PAYBYPHONE_PASSWORD, PAYBYPHONE_USERNAME, PAYBYPHONE_LICENSEPLATE, PAYBYPHONE_ZIPCODE, PAYBYPHONE_CARDNUMBER'
|
70
60
|
end
|
71
61
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
module ParkingTicket
|
3
|
+
module Client
|
4
|
+
module PayByPhone
|
5
|
+
class Request
|
6
|
+
def initialize(configuration)
|
7
|
+
@configuration = configuration
|
8
|
+
end
|
9
|
+
|
10
|
+
def tickets(account_id)
|
11
|
+
connection.get("/parking/accounts/#{account_id}/sessions?periodType=Current").body
|
12
|
+
end
|
13
|
+
|
14
|
+
def new_ticket(_account_id, _parking_start_time, _quote_id, _payment_method_id)
|
15
|
+
connection.post(
|
16
|
+
"/parking/accounts/#{account_id}/sessions/",
|
17
|
+
{
|
18
|
+
"expireTime": nil,
|
19
|
+
"duration": {
|
20
|
+
"quantity": '1',
|
21
|
+
"timeUnit": 'days'
|
22
|
+
},
|
23
|
+
"licensePlate": @configuration.license_plate,
|
24
|
+
"locationId": @configuration.zipcode,
|
25
|
+
"rateOptionId": '75101',
|
26
|
+
"startTime": parking_start_time,
|
27
|
+
"quoteId": quote_id,
|
28
|
+
"parkingAccountId": account_id,
|
29
|
+
"paymentMethod": {
|
30
|
+
"paymentMethodType": 'PaymentAccount',
|
31
|
+
"payload": {
|
32
|
+
"paymentAccountId": payment_method_id,
|
33
|
+
"clientBrowserDetails": {
|
34
|
+
"browserAcceptHeader": 'text/html',
|
35
|
+
"browserColorDepth": '30',
|
36
|
+
"browserJavaEnabled": 'false',
|
37
|
+
"browserLanguage": 'fr-FR',
|
38
|
+
"browserScreenHeight": '900',
|
39
|
+
"browserScreenWidth": '1440',
|
40
|
+
"browserTimeZone": '-60',
|
41
|
+
"browserUserAgent": 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}.to_json
|
46
|
+
).body
|
47
|
+
end
|
48
|
+
|
49
|
+
def accounts
|
50
|
+
connection.get('/parking/accounts').body
|
51
|
+
end
|
52
|
+
|
53
|
+
def vehicles
|
54
|
+
connection.get('/identity/profileservice/v1/members/vehicles/paybyphone').body
|
55
|
+
end
|
56
|
+
|
57
|
+
def rate_options(account_id)
|
58
|
+
connection.get("/parking/locations/#{@configuration.zipcode}/rateOptions",
|
59
|
+
{
|
60
|
+
parkingAccountId: account_id,
|
61
|
+
licensePlate: @configuration.license_plate
|
62
|
+
}).body
|
63
|
+
end
|
64
|
+
|
65
|
+
def new_quote(rate_option_id, account_id)
|
66
|
+
connection.get(
|
67
|
+
"/parking/accounts/#{account_id}/quote",
|
68
|
+
{
|
69
|
+
locationId: @configuration.zipcode,
|
70
|
+
licensePlate: @configuration.license_plate,
|
71
|
+
rateOptionId: rate_option_id,
|
72
|
+
durationTimeUnit: 'Days',
|
73
|
+
durationQuantity: 1,
|
74
|
+
isParkUntil: false,
|
75
|
+
parkingAccountId: account_id
|
76
|
+
}
|
77
|
+
).body
|
78
|
+
end
|
79
|
+
|
80
|
+
def member
|
81
|
+
connection.get('/identity/profileservice/v1/members').body
|
82
|
+
end
|
83
|
+
|
84
|
+
def payment_methods
|
85
|
+
connection.get('/payment/v3/accounts').body
|
86
|
+
end
|
87
|
+
|
88
|
+
def connection
|
89
|
+
@connection ||= Faraday.new(
|
90
|
+
url: 'https://consumer.paybyphoneapis.com',
|
91
|
+
headers: {
|
92
|
+
'Content-Type' => 'application/json',
|
93
|
+
'Authorization' => "Bearer #{token}"
|
94
|
+
}
|
95
|
+
) do |f|
|
96
|
+
f.response :json
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def token
|
101
|
+
conn = Faraday.new('https://auth.paybyphoneapis.com') do |f|
|
102
|
+
f.response :json
|
103
|
+
end
|
104
|
+
conn.post(
|
105
|
+
'/token',
|
106
|
+
URI.encode_www_form({
|
107
|
+
grant_type: 'password',
|
108
|
+
username: @configuration.username,
|
109
|
+
password: @configuration.password,
|
110
|
+
client_id: 'paybyphone_web'
|
111
|
+
}),
|
112
|
+
{
|
113
|
+
'Accept' => 'application/json, text/plain, */*',
|
114
|
+
'X-Pbp-ClientType' => 'WebApp'
|
115
|
+
}
|
116
|
+
).body['access_token']
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ParkingTicket
|
2
|
+
class Configuration
|
3
|
+
def self.attr_required(*configuration_keys)
|
4
|
+
define_method('attr_required') do
|
5
|
+
configuration_keys
|
6
|
+
end
|
7
|
+
configuration_keys.each do |configuration_key|
|
8
|
+
define_method configuration_key.to_s do
|
9
|
+
instance_variable_get("@#{configuration_key}")
|
10
|
+
end
|
11
|
+
define_method "#{configuration_key}=" do |value|
|
12
|
+
instance_variable_set("@#{configuration_key}", value)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@attr_required = defined?(attr_required) ? attr_required : []
|
19
|
+
yield(self)
|
20
|
+
end
|
21
|
+
|
22
|
+
def completed?
|
23
|
+
@attr_required.all? { |attribute_required| instance_variable_get("@#{attribute_required}") }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/parking_ticket.rb
CHANGED
@@ -1,28 +1,66 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
require 'parking_ticket/configuration'
|
4
|
+
require 'parking_ticket/version'
|
5
|
+
|
6
|
+
# PayByPhone wrapper
|
7
|
+
require 'client/pay_by_phone/configuration'
|
8
|
+
require 'client/pay_by_phone/adapter'
|
9
|
+
require 'client/pay_by_phone/request'
|
6
10
|
|
7
11
|
module ParkingTicket
|
8
|
-
class
|
12
|
+
class Base
|
13
|
+
attr_reader :configuration
|
9
14
|
|
10
|
-
|
11
|
-
if current_ticket
|
12
|
-
puts '❌ Can not renew ticket as already covered by a ticket at this time'
|
13
|
-
else
|
14
|
-
puts '🔄 Renewing ticket'
|
15
|
-
adapter.renew
|
16
|
-
puts '✅ Ticket renewed'
|
15
|
+
class Error < StandardError
|
17
16
|
end
|
18
|
-
end
|
19
17
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
def initialize(adapter_name, configuration_attributes)
|
19
|
+
@adapter_name = adapter_name
|
20
|
+
@configuration_attributes = configuration_attributes
|
21
|
+
@result = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
def adapter
|
25
|
+
@adapter ||= load_adapter!
|
26
|
+
end
|
27
|
+
|
28
|
+
def renew
|
29
|
+
adapter.renew unless current_ticket
|
30
|
+
end
|
31
|
+
|
32
|
+
def current_ticket
|
33
|
+
adapter.current_ticket
|
34
|
+
end
|
24
35
|
|
25
|
-
|
26
|
-
|
36
|
+
private
|
37
|
+
|
38
|
+
def load_adapter!
|
39
|
+
return prepare_pay_by_phone_adapter! if @adapter_name == 'pay_by_phone'
|
40
|
+
return prepare_easy_park_adapter! if @adapter_name == 'easy_park'
|
41
|
+
|
42
|
+
raise Error, "Unhandled adapter : #{@adapter_name}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def prepare_pay_by_phone_adapter!
|
46
|
+
configuration = pay_by_phone_configuration
|
47
|
+
return Client::PayByPhone::Adapter.new(configuration) if configuration.completed?
|
48
|
+
|
49
|
+
raise Error, 'Uncompleted configuration'
|
50
|
+
end
|
51
|
+
|
52
|
+
def pay_by_phone_configuration
|
53
|
+
Client::PayByPhone::Configuration.new do |config|
|
54
|
+
config.username = @configuration_attributes[:username]
|
55
|
+
config.password = @configuration_attributes[:password]
|
56
|
+
config.license_plate = @configuration_attributes[:license_plate]
|
57
|
+
config.zipcode = @configuration_attributes[:zipcode]
|
58
|
+
config.card_number = @configuration_attributes[:card_number]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def prepare_easy_park_adapter!
|
63
|
+
raise Error, 'EasyPark will be handled in the next major release'
|
64
|
+
end
|
27
65
|
end
|
28
66
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parking_ticket
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Ecrepont
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-01-
|
11
|
+
date: 2023-01-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -40,12 +40,12 @@ files:
|
|
40
40
|
- Rakefile
|
41
41
|
- bin/console
|
42
42
|
- bin/setup
|
43
|
-
- lib/client/pay_by_phone.rb
|
44
43
|
- lib/client/pay_by_phone/adapter.rb
|
44
|
+
- lib/client/pay_by_phone/configuration.rb
|
45
|
+
- lib/client/pay_by_phone/request.rb
|
45
46
|
- lib/parking_ticket.rb
|
46
|
-
- lib/parking_ticket/
|
47
|
+
- lib/parking_ticket/configuration.rb
|
47
48
|
- lib/parking_ticket/version.rb
|
48
|
-
- parking_ticket.gemspec
|
49
49
|
homepage: https://github.com/troptropcontent/parking_ticket
|
50
50
|
licenses:
|
51
51
|
- MIT
|
data/lib/client/pay_by_phone.rb
DELETED
@@ -1,113 +0,0 @@
|
|
1
|
-
require 'faraday'
|
2
|
-
class PayByPhone
|
3
|
-
def tickets(account_id)
|
4
|
-
connection.get("/parking/accounts/#{account_id}/sessions?periodType=Current").body
|
5
|
-
end
|
6
|
-
|
7
|
-
def new_ticket(account_id, parking_start_time, quote_id, payment_method_id)
|
8
|
-
connection.post(
|
9
|
-
"/parking/accounts/#{account_id}/sessions/",
|
10
|
-
{
|
11
|
-
"expireTime": nil,
|
12
|
-
"duration": {
|
13
|
-
"quantity": '1',
|
14
|
-
"timeUnit": 'days'
|
15
|
-
},
|
16
|
-
"licensePlate": ENV['PAYBYPHONE_LICENSEPLATE'],
|
17
|
-
"locationId": ENV['PAYBYPHONE_ZIPCODE'],
|
18
|
-
"rateOptionId": '75101',
|
19
|
-
"startTime": parking_start_time,
|
20
|
-
"quoteId": quote_id,
|
21
|
-
"parkingAccountId": account_id,
|
22
|
-
"paymentMethod": {
|
23
|
-
"paymentMethodType": 'PaymentAccount',
|
24
|
-
"payload": {
|
25
|
-
"paymentAccountId": payment_method_id,
|
26
|
-
"clientBrowserDetails": {
|
27
|
-
"browserAcceptHeader": 'text/html',
|
28
|
-
"browserColorDepth": '30',
|
29
|
-
"browserJavaEnabled": 'false',
|
30
|
-
"browserLanguage": 'fr-FR',
|
31
|
-
"browserScreenHeight": '900',
|
32
|
-
"browserScreenWidth": '1440',
|
33
|
-
"browserTimeZone": '-60',
|
34
|
-
"browserUserAgent": 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'
|
35
|
-
}
|
36
|
-
}
|
37
|
-
}
|
38
|
-
}.to_json
|
39
|
-
).body
|
40
|
-
end
|
41
|
-
|
42
|
-
def accounts
|
43
|
-
connection.get('/parking/accounts').body
|
44
|
-
end
|
45
|
-
|
46
|
-
def vehicles
|
47
|
-
connection.get('/identity/profileservice/v1/members/vehicles/paybyphone').body
|
48
|
-
end
|
49
|
-
|
50
|
-
def rate_options(account_id)
|
51
|
-
connection.get("/parking/locations/#{ENV['PAYBYPHONE_ZIPCODE']}/rateOptions",
|
52
|
-
{
|
53
|
-
parkingAccountId: account_id,
|
54
|
-
licensePlate: ENV['PAYBYPHONE_LICENSEPLATE']
|
55
|
-
}).body
|
56
|
-
end
|
57
|
-
|
58
|
-
def new_quote(rate_option_id, account_id)
|
59
|
-
connection.get(
|
60
|
-
"/parking/accounts/#{account_id}/quote",
|
61
|
-
{
|
62
|
-
locationId: ENV['PAYBYPHONE_ZIPCODE'],
|
63
|
-
licensePlate: ENV['PAYBYPHONE_LICENSEPLATE'],
|
64
|
-
rateOptionId: rate_option_id,
|
65
|
-
durationTimeUnit: 'Days',
|
66
|
-
durationQuantity: 1,
|
67
|
-
isParkUntil: false,
|
68
|
-
parkingAccountId: account_id
|
69
|
-
}
|
70
|
-
).body
|
71
|
-
end
|
72
|
-
|
73
|
-
def member
|
74
|
-
connection.get('/identity/profileservice/v1/members').body
|
75
|
-
end
|
76
|
-
|
77
|
-
def payment_methods
|
78
|
-
connection.get('/payment/v3/accounts').body
|
79
|
-
end
|
80
|
-
|
81
|
-
private
|
82
|
-
|
83
|
-
def connection
|
84
|
-
@connection ||= Faraday.new(
|
85
|
-
url: 'https://consumer.paybyphoneapis.com',
|
86
|
-
headers: {
|
87
|
-
'Content-Type' => 'application/json',
|
88
|
-
'Authorization' => "Bearer #{token}"
|
89
|
-
}
|
90
|
-
) do |f|
|
91
|
-
f.response :json
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def token
|
96
|
-
conn = Faraday.new('https://auth.paybyphoneapis.com') do |f|
|
97
|
-
f.response :json
|
98
|
-
end
|
99
|
-
conn.post(
|
100
|
-
'/token',
|
101
|
-
URI.encode_www_form({
|
102
|
-
grant_type: 'password',
|
103
|
-
username: ENV['PAYBYPHONE_USERNAME'],
|
104
|
-
password: ENV['PAYBYPHONE_PASSWORD'],
|
105
|
-
client_id: 'paybyphone_web'
|
106
|
-
}),
|
107
|
-
{
|
108
|
-
'Accept' => 'application/json, text/plain, */*',
|
109
|
-
'X-Pbp-ClientType' => 'WebApp'
|
110
|
-
}
|
111
|
-
).body['access_token']
|
112
|
-
end
|
113
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
class ParkingTicket::Ticket
|
2
|
-
def initialize(attributes)
|
3
|
-
@starts_on = attributes[:starts_on]
|
4
|
-
@ends_on = attributes[:ends_on]
|
5
|
-
@license_plate = attributes[:license_plate]
|
6
|
-
@cost = attributes[:cost]
|
7
|
-
@client = attributes[:client]
|
8
|
-
@client_ticket_id = attributes[:client_ticket_id]
|
9
|
-
end
|
10
|
-
|
11
|
-
def to_h
|
12
|
-
{
|
13
|
-
starts_on: @starts_on,
|
14
|
-
ends_on: @ends_on,
|
15
|
-
license_plate: @license_plate,
|
16
|
-
cost: @cost,
|
17
|
-
client: @client,
|
18
|
-
client_ticket_id: @client_ticket_id
|
19
|
-
}
|
20
|
-
end
|
21
|
-
end
|
data/parking_ticket.gemspec
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'lib/parking_ticket/version'
|
4
|
-
|
5
|
-
Gem::Specification.new do |spec|
|
6
|
-
spec.name = 'parking_ticket'
|
7
|
-
spec.version = ParkingTicket::VERSION
|
8
|
-
spec.authors = ['Tom Ecrepont']
|
9
|
-
spec.email = ['tomecrepont@gmail.com']
|
10
|
-
|
11
|
-
spec.summary = 'Never forget to take a parking ticket again.'
|
12
|
-
spec.description = 'Automatically renew your parking ticket when it expires.'
|
13
|
-
spec.homepage = 'https://github.com/troptropcontent/parking_ticket'
|
14
|
-
spec.license = 'MIT'
|
15
|
-
spec.required_ruby_version = '>= 3.0.0'
|
16
|
-
|
17
|
-
spec.metadata['homepage_uri'] = spec.homepage
|
18
|
-
spec.metadata['source_code_uri'] = 'https://github.com/troptropcontent/parking_ticket'
|
19
|
-
|
20
|
-
# Specify which files should be added to the gem when it is released.
|
21
|
-
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
22
|
-
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
23
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
24
|
-
(f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
25
|
-
end
|
26
|
-
end
|
27
|
-
spec.bindir = 'exe'
|
28
|
-
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
29
|
-
spec.require_paths = ['lib']
|
30
|
-
|
31
|
-
# dependancies
|
32
|
-
spec.add_dependency 'faraday'
|
33
|
-
end
|