suez_mon_eau 0.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 +7 -0
- checksums.yaml.gz.sig +0 -0
- data/bin/suez_mon_eau +30 -0
- data/lib/suez_mon_eau.rb +128 -0
- data.tar.gz.sig +2 -0
- metadata +193 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5bb0b63f4f8e9e1da600d92123d83c4cd4998674d160e94ddd2ac238542d5c3b
|
4
|
+
data.tar.gz: e449685d94f7a73e1e46a86979164c91640ca3fdfb2d23b05e5df50142eca8f2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7769f819f65e6e9ef84827a50d40c7c8e7c1bd601859345b3aebc220ab4154522cb88e06257b2e89e99dddc4c30d4a3d93783783bcb26d253e29ce5a34b9324b
|
7
|
+
data.tar.gz: 684487bd9e82fb073377fdcb2eaec9dee4dc2568acbc61b2b5cc3d544e05c0ec1b946a7e9fdc8e718fdb930e85ec9ee7831d1f9d2b4dcb7be4e0da887c768a25
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data/bin/suez_mon_eau
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby -Ilib
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'suez_mon_eau'
|
5
|
+
require 'date'
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
options = {}
|
9
|
+
opt_parser=OptionParser.new do |p|
|
10
|
+
p.banner = "Usage: #{$PROGRAM_NAME} [options]"
|
11
|
+
p.on('-u', '--username USER', 'Portal username', String){|v|options[:username] = v}
|
12
|
+
p.on('-p', '--password PASS', 'Portal password', String){|v|options[:password] = v}
|
13
|
+
p.on('-P', '--provider PROVIDER', 'Water Provider (Default: Suez)', String){|v|options[:provider] = v}
|
14
|
+
p.on('-i', '--id ID', 'Counter identifier', String){|v|options[:id] = v}
|
15
|
+
p.on('-d', '--debug', 'Turn on Rest trace', String){RestClient.log=$stderr}
|
16
|
+
end
|
17
|
+
opt_parser.parse!
|
18
|
+
if %i[username password].any?{|i|options[i].nil?}
|
19
|
+
puts opt_parser
|
20
|
+
exit 1
|
21
|
+
end
|
22
|
+
suez = SuezMonEau.new(**options)
|
23
|
+
puts('Contracts:')
|
24
|
+
pp suez.contracts
|
25
|
+
puts('Recent:')
|
26
|
+
pp suez.monthly_recent
|
27
|
+
puts('This Month:')
|
28
|
+
pp suez.daily_for_month(DateTime.now)
|
29
|
+
puts('Current:')
|
30
|
+
pp suez.total_volume
|
data/lib/suez_mon_eau.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rest-client'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
# Volumes in m³
|
7
|
+
class SuezMonEau
|
8
|
+
VERSION='0.1'
|
9
|
+
GEM_NAME='suez_mon_eau'
|
10
|
+
SRC_URL='https://github.com/laurent-martin/ruby-suez-mon-eau'
|
11
|
+
DOC_URL='https://github.com/laurent-martin/ruby-suez-mon-eau'
|
12
|
+
GEM_URL='https://github.com/laurent-martin/ruby-suez-mon-eau'
|
13
|
+
BASE_URIS = {
|
14
|
+
'Suez' => 'https://www.toutsurmoneau.fr/mon-compte-en-ligne',
|
15
|
+
'Eau Olivet' => 'https://www.eau-olivet.fr/mon-compte-en-ligne'
|
16
|
+
}.freeze
|
17
|
+
API_ENDPOINT_LOGIN = 'je-me-connecte'
|
18
|
+
# daily (Jours) : /Y/m/counterid : Array(JJMMYYY, daily volume, cumulative volume). Volumes: .xxx
|
19
|
+
API_ENDPOINT_DAILY = 'statJData'
|
20
|
+
# monthly (Mois) : /counterid : Array(mmm. yy, monthly volume, cumulative voume, Mmmmm YYYY)
|
21
|
+
API_ENDPOINT_MONTHLY = 'statMData'
|
22
|
+
API_ENDPOINT_CONTRAT = 'donnees-contrats'
|
23
|
+
PAGE_CONSO = 'historique-de-consommation-tr'
|
24
|
+
SESSION_ID = 'eZSESSID'
|
25
|
+
MONTHS = %w[Janvier Février Mars Avril Mai Juin Juillet Août Septembre Octobre Novembre Décembre].freeze
|
26
|
+
private_constant :BASE_URIS,:API_ENDPOINT_LOGIN,:API_ENDPOINT_DAILY,:API_ENDPOINT_MONTHLY,:API_ENDPOINT_CONTRAT,:PAGE_CONSO,:SESSION_ID,:MONTHS
|
27
|
+
|
28
|
+
# @param provider optional, one of supported providers or base url
|
29
|
+
def initialize(username:, password:, id: nil, provider: 'Suez')
|
30
|
+
@base_uri = BASE_URIS[provider] || provider
|
31
|
+
raise 'Not a valid provider' if @base_uri.nil?
|
32
|
+
@username = username
|
33
|
+
@password = password
|
34
|
+
@id = id
|
35
|
+
@id=nil if @id.is_a?(String) && @id.empty?
|
36
|
+
@cookies = nil
|
37
|
+
return unless @id.nil?
|
38
|
+
update_access_cookie
|
39
|
+
conso_page=RestClient.get("#{@base_uri}/#{PAGE_CONSO}",cookies: @cookies)
|
40
|
+
# get counter id from page
|
41
|
+
raise 'Could not retrieve counter id' unless (token_match = conso_page.body.match(%r{/month/([0-9]+)}))
|
42
|
+
@id=token_match[1]
|
43
|
+
end
|
44
|
+
|
45
|
+
def update_access_cookie
|
46
|
+
initial_response = RestClient.get("#{@base_uri}/#{API_ENDPOINT_LOGIN}")
|
47
|
+
raise 'Could not get token' unless (token_match = initial_response.body.match(%r{_csrf_token" value="(.*)"/>}))
|
48
|
+
data = {
|
49
|
+
'_csrf_token' => token_match[1],
|
50
|
+
'_username' => @username,
|
51
|
+
'_password' => @password,
|
52
|
+
'signin[username]' => @username,
|
53
|
+
'signin[password]' => nil,
|
54
|
+
'tsme_user_login[_username]' => @username,
|
55
|
+
'tsme_user_login[_password]' => @password
|
56
|
+
}
|
57
|
+
# There is a redirect (302) on POST
|
58
|
+
response = RestClient.post("#{@base_uri}/#{API_ENDPOINT_LOGIN}", data,
|
59
|
+
{ cookies: initial_response.cookies }) do |resp, _req, _res|
|
60
|
+
case resp.code
|
61
|
+
when 301, 302, 307
|
62
|
+
begin
|
63
|
+
resp.follow_redirection
|
64
|
+
rescue RestClient::Found
|
65
|
+
raise 'Check username and password'
|
66
|
+
end
|
67
|
+
else resp.return!
|
68
|
+
end
|
69
|
+
end
|
70
|
+
raise StandardError, 'Login error: Please check your username/password.' unless response.cookies.key?(SESSION_ID)
|
71
|
+
@cookies = { SESSION_ID => response.cookies[SESSION_ID] }
|
72
|
+
end
|
73
|
+
|
74
|
+
def call_api(method:, endpoint:)
|
75
|
+
retried = false
|
76
|
+
loop do
|
77
|
+
update_access_cookie if @cookies.nil?
|
78
|
+
resp = RestClient::Request.execute(method: method, url: "#{@base_uri}/#{endpoint}", cookies: @cookies)
|
79
|
+
return JSON.parse(resp.body) if resp.headers[:content_type].include?('application/json')
|
80
|
+
raise 'Failed refreshing cookie' if retried
|
81
|
+
retried = true
|
82
|
+
@cookies = nil
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def contracts
|
87
|
+
call_api(method: :get, endpoint: API_ENDPOINT_CONTRAT)
|
88
|
+
end
|
89
|
+
|
90
|
+
# @param thedate [Date] use year and month, built with Date.new(year,month,1)
|
91
|
+
# @return Hash [day_in_month]={day:, total:}
|
92
|
+
def daily_for_month(thedate)
|
93
|
+
r = call_api(method: :get, endpoint: "#{API_ENDPOINT_DAILY}/#{thedate.year}/#{thedate.month}/#{@id}")
|
94
|
+
# since the month is known, keep only day
|
95
|
+
r.each_with_object({}) do |i, m|
|
96
|
+
m[i[0].split('-').last.to_i] = { day: i[1], total: i[2] } unless i[2].eql?(0)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# @returns [Hash]
|
101
|
+
def monthly_recent
|
102
|
+
resp = call_api(method: :get, endpoint: "#{API_ENDPOINT_MONTHLY}/#{@id}")
|
103
|
+
h = {}
|
104
|
+
result = {
|
105
|
+
history: h,
|
106
|
+
total_volume: nil,
|
107
|
+
highest_monthly_volume: resp.pop,
|
108
|
+
last_year_volume: resp.pop,
|
109
|
+
this_year_volume: resp.pop
|
110
|
+
}
|
111
|
+
# fill history by hear and month
|
112
|
+
resp.each do |i|
|
113
|
+
# skip futures
|
114
|
+
next if i[2].eql?(0)
|
115
|
+
# date is Month Year
|
116
|
+
d = i[3].split(' ')
|
117
|
+
year = d.last.to_i
|
118
|
+
month = 1 + MONTHS.find_index(d.first)
|
119
|
+
h[year] ||= {}
|
120
|
+
h[year][month] = { month: i[1], total: result[:total_volume] = i[2] }
|
121
|
+
end
|
122
|
+
result
|
123
|
+
end
|
124
|
+
|
125
|
+
def total_volume
|
126
|
+
monthly_recent[:total_volume]
|
127
|
+
end
|
128
|
+
end
|
data.tar.gz.sig
ADDED
@@ -0,0 +1,2 @@
|
|
1
|
+
�ȶ7�E��l�R1�^O[W�ӈ��^�*����0�>��D�͜��țB��>PҩI]τ�8�'���JK[`�X͂��ȋWT*�U�J@�<9Xk���w_s+�St{�3�v���jC:�Z������?�V2e]ܯ4��
|
2
|
+
_�{b7��jnC�%�cK.n9o��Z�0!���HHuQ��P�ƍ��x�P�XUm���gJ"qxX�,87Y�=�#$�I���(��]֝��b�'�>�&d�k�x9p�C���Ūp��F��?Z����&��40���4����ut�l���e����P,�"BT����7�ͺyi&7!X�C�"����_����E&�wtw�sh5^��d�����JX��_�e����K@W6շa�
|
metadata
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: suez_mon_eau
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Laurent Martin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIEkjCCAvqgAwIBAgIBATANBgkqhkiG9w0BAQsFADBHMRkwFwYDVQQDDBBsYXVy
|
14
|
+
ZW50Lm1hcnRpbi5sMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/Is
|
15
|
+
ZAEZFgNjb20wHhcNMjIxMjMwMTAyNjM0WhcNMjMxMjMwMTAyNjM0WjBHMRkwFwYD
|
16
|
+
VQQDDBBsYXVyZW50Lm1hcnRpbi5sMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzAR
|
17
|
+
BgoJkiaJk/IsZAEZFgNjb20wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIB
|
18
|
+
gQDZloSHnbKkBEh6fW03mhvaNkUsiyO3iPbXnE7cosW3VUIzXvDeNTMVkeDnqjA8
|
19
|
+
lW5jKb0MHaymJXjuybck0kGQNwtCPVl5m9e5lAqALVWYyI7K2XKfvl11/ai0tA5g
|
20
|
+
sZdcxJkCsBBeKrEUPAw/9pNEPwtWu+5MtYxK8gXvP5mNPQs+NZx42Wksgu+DO/tk
|
21
|
+
Ph/W9f4TWB6rrOq7xm7YzG8jYHRISV2fyW7NqpB6lB9y8444IosCz9RQ/fGcIdIg
|
22
|
+
LjnvX5rofI6IDfTbUq9fvkT3ZbrxgTzY09lG7heDrgL1L7a+U5G4FF1PNzmZxgqj
|
23
|
+
z+xU6mfaVVY1hgGK6EsDgsyM7QEcOGU5witL2yUkw3jYGm8jF3YdoSoZW+MKPfNf
|
24
|
+
v6yNTGJsJAVXlo//g+HRS6KGSfTx5M7cgRxGgud72h3PlOxgO/t8d7MTmRuo1oeU
|
25
|
+
pVmEUUsVtDSUJ3bdL5W85LCIV02VBPtw/rrg6AHFbrHRnp7FWcN1i20x+sk5ZBa4
|
26
|
+
C08CAwEAAaOBiDCBhTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU
|
27
|
+
IXrSEupwwYfE3a9f2jVz1wp4KGwwJQYDVR0RBB4wHIEabGF1cmVudC5tYXJ0aW4u
|
28
|
+
bEBnbWFpbC5jb20wJQYDVR0SBB4wHIEabGF1cmVudC5tYXJ0aW4ubEBnbWFpbC5j
|
29
|
+
b20wDQYJKoZIhvcNAQELBQADggGBAAhSXNutSwyrmpo/E/Fj3gNbMEL7uteveQ9J
|
30
|
+
jzsyp02PR6gaCkAIBWHigYTSI6+AW6vfFrCcRU7mVpGFDDTtYIZsthOU7G2mG0IY
|
31
|
+
uMXqZERShk+IjzpTDYQjvsmrQ7paQ7XYm1pS3cYzQqSwWP7unIcl0w13/JEcrQpz
|
32
|
+
w9Nk/JfICyOwnsNsGq/0SNSdrlNr1qUQQM/nmMEM6AvpKp7I4P2Ap4VJkDCu+0SK
|
33
|
+
x3mBvWB8GtmMOpto9ybr7El4xjfJpNu/kvKv2bbCQPs6Z/qfz0lYyK5JFqmhpQN7
|
34
|
+
E1Wj9oKIf+RH/1FYBdx2TaQ1ijkqpfwTa0QWRY4dU/GKGgBmMriGMIh8YAL9cmgd
|
35
|
+
HdwIbOaZ+pjC4nKKT38vsb2lNismhhaiAYq+Ekld50Rb0nbCPq7VfREn8uCJatpb
|
36
|
+
47kCk6UoPFdRvzdrQoOHQhkBuabk02iz6c35KbcKaogX8SDehA1/bO4F4VwLz4in
|
37
|
+
YmwAMTElT6RjOw71pAJ02LbhHG02SA==
|
38
|
+
-----END CERTIFICATE-----
|
39
|
+
date: 2022-12-30 00:00:00.000000000 Z
|
40
|
+
dependencies:
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rest-client
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.12'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.12'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-ast
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.4'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.4'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop-performance
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.10'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.10'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop-shopify
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '2.0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '2.0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: simplecov
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.18'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.18'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: solargraph
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0.44'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0.44'
|
153
|
+
description: Retrieve water usage information from Suez in France
|
154
|
+
email:
|
155
|
+
- laurent.martin.l@gmail.com
|
156
|
+
executables:
|
157
|
+
- suez_mon_eau
|
158
|
+
extensions: []
|
159
|
+
extra_rdoc_files: []
|
160
|
+
files:
|
161
|
+
- bin/suez_mon_eau
|
162
|
+
- lib/suez_mon_eau.rb
|
163
|
+
homepage: https://github.com/laurent-martin/ruby-suez-mon-eau
|
164
|
+
licenses:
|
165
|
+
- Apache-2.0
|
166
|
+
metadata:
|
167
|
+
allowed_push_host: https://rubygems.org
|
168
|
+
homepage_uri: https://github.com/laurent-martin/ruby-suez-mon-eau
|
169
|
+
source_code_uri: https://github.com/laurent-martin/ruby-suez-mon-eau
|
170
|
+
changelog_uri: https://github.com/laurent-martin/ruby-suez-mon-eau
|
171
|
+
rubygems_uri: https://github.com/laurent-martin/ruby-suez-mon-eau
|
172
|
+
documentation_uri: https://github.com/laurent-martin/ruby-suez-mon-eau
|
173
|
+
post_install_message:
|
174
|
+
rdoc_options: []
|
175
|
+
require_paths:
|
176
|
+
- lib
|
177
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - ">="
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '2.4'
|
182
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: '0'
|
187
|
+
requirements:
|
188
|
+
- No specific requirement
|
189
|
+
rubygems_version: 3.3.7
|
190
|
+
signing_key:
|
191
|
+
specification_version: 4
|
192
|
+
summary: Retrieve water usage information from Suez in France
|
193
|
+
test_files: []
|
metadata.gz.sig
ADDED
Binary file
|