lws 7.0.1 → 7.1.2

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: df2e6e2da0a65bfe4f58710cd8d2e126d84b11a7d69032f8770019e9818b3c81
4
- data.tar.gz: 381ab842c1653517ccafeefe6923d62559816e0546362b90a3803dffac91bc0c
3
+ metadata.gz: a6ddf096778ba5030a935df95f904a65776bbd8b2dd30602e3c9d912124fb5cd
4
+ data.tar.gz: 739154dc2c9598eef580f9a562cff9ddccde3a0828e985c55429ceed74f03a5d
5
5
  SHA512:
6
- metadata.gz: fcee2864386b9c6e6c8d0a0a205e284f30ef40be1063079158be5618a8fe8e6bbc5b3d676f2fd12e39857bb3763d604efebea3c8477d80f9af6220dc6dc53b15
7
- data.tar.gz: fd4da59a819e77accca4ade09513c1e5b2f60005173cd9372fb6e6172ceae5a4a5d3d43d2e70579372e43833b85e3091ca46e8b2ae8eae209321f359f5e7e8b9
6
+ metadata.gz: c6f4e39e00a7277ed012c6d4a2a846dae249edf892db185d17c5a62efa012902bc388ed4e652a26e25eb30ea07e208fbe4ef08b19671c750a0e3f33aa719f8a5
7
+ data.tar.gz: 696ae43f1ed90d4674365f86d63d411fc21544cce16ba250079e0bcefef1143c9d908c6e01b18773b006fa9a704e45ebc85795ff044c28948bf16fb79f4da042
@@ -134,7 +134,11 @@ end
134
134
 
135
135
  # Set up Pry
136
136
  FileUtils.mkdir_p("#{ENV['HOME']}/.local/share/LeftClick")
137
- Pry.config.history.file = "#{ENV['HOME']}/.local/share/LeftClick/lws_history"
137
+ if Pry.config.history_file
138
+ Pry.config.history_file = "#{ENV['HOME']}/.local/share/LeftClick/lws_history"
139
+ else
140
+ Pry.config.history.file = "#{ENV['HOME']}/.local/share/LeftClick/lws_history"
141
+ end
138
142
  Pry.config.prompt_name = PROG_NAME
139
143
 
140
144
  # Print an LWS setup summary
data/lib/lws.rb CHANGED
@@ -60,7 +60,7 @@ module LWS
60
60
  # config.api_token_middleware = TokenAuthenticator
61
61
  # config.caching_object = MyRedisCache.new
62
62
  # config.environment = :development
63
- # config.endponts = { maps: "https://maps.leftclick.cloud" }
63
+ # config.endpoints = { maps: "https://maps.leftclick.cloud" }
64
64
  # config.http_debug = true
65
65
  # config.json_debug = true
66
66
  # config.logger = Rails.logger
@@ -78,6 +78,10 @@ module LWS::DigitalSignage
78
78
  # @return [Array<Channel::Group>] the groups the channel is a member of
79
79
  has_many :groups, class_name: "LWS::DigitalSignage::Channel::Group"
80
80
 
81
+ # @!attribute marquee_config
82
+ # @return [String] the marquee/ticker tape configuration (JSON) of the channel
83
+ attribute :marquee_config
84
+
81
85
  # @!attribute name
82
86
  # @return [String] the name of the channel
83
87
  attribute :name
@@ -100,6 +104,10 @@ module LWS::DigitalSignage
100
104
  # @return [Boolean] whether remote control is enabled for the channel
101
105
  attribute :remote_control
102
106
 
107
+ # @!attribute slides
108
+ # @return [Array<Slide>] the slides schedules on the channel
109
+ has_many :slides, class_name: "LWS::DigitalSignage::Slide"
110
+
103
111
  # @!attribute tags
104
112
  # @return [Array<Channel::Tag>] the tags of the channel
105
113
  has_many :tags, class_name: "LWS::DigitalSignage::Channel::Tag"
@@ -159,6 +167,10 @@ module LWS::DigitalSignage
159
167
  # @return [Integer, nil] the ID of the parent group of the channel group
160
168
  attribute :parent_id
161
169
 
170
+ # @!attribute slides
171
+ # @return [Array<Slide>] the slides schedules on the channel group
172
+ has_many :slides, class_name: "LWS::DigitalSignage::Slide"
173
+
162
174
  #@!attribute tags
163
175
  # @return [Array<Channel::Group::Tag>] the tags of the channel group
164
176
  has_many :tags, class_name: "LWS::DigitalSignage::Channel::Group::Tag",
@@ -579,6 +591,10 @@ module LWS::DigitalSignage
579
591
  # @!attribute name
580
592
  # @return [String] the name of the layout category
581
593
  attribute :name
594
+
595
+ # @!attribute translated_name
596
+ # @return [String] the translated name of the layout category
597
+ attribute :name
582
598
  end
583
599
 
584
600
  # = The layout element class
@@ -628,6 +644,10 @@ module LWS::DigitalSignage
628
644
  # element
629
645
  has_many :properties, class_name: "LWS::DigitalSignage::Layout::Element::Property"
630
646
 
647
+ # @!attribute title
648
+ # @return [String, nil] the title of the layout element
649
+ attribute :title
650
+
631
651
  # @!attribute version
632
652
  # @return [Layout::Verion] the layout version that contains the element
633
653
  # FIXME: Missing endpoint in LWS
@@ -713,6 +733,10 @@ module LWS::DigitalSignage
713
733
  # version
714
734
  has_many :elements, class_name: "LWS::DigitalSignage::Layout::Element"
715
735
 
736
+ # @!attribute height
737
+ # @return [Integer] the intended height of the layout version
738
+ attribute :width
739
+
716
740
  # @!attribute layout
717
741
  # @return [Layout] the layout the layout version is for
718
742
  belongs_to :layout
@@ -720,6 +744,28 @@ module LWS::DigitalSignage
720
744
  # @!attribute layout_id
721
745
  # @return [Integer] the ID of the layout the layout version is for
722
746
  attribute :layout_id
747
+
748
+ # @!attribute rotation
749
+ # @return ["landscape", "portrait"] the rotation (orientation) of the
750
+ # layout version
751
+ attribute :rotation
752
+
753
+ # @!attribute rotation_angle
754
+ # @return [0, 90] the rotation angle of the layout version
755
+ attribute :rotation_angle
756
+
757
+ # @!attribute status [r]
758
+ # @return ["initializing", "creating_pack", "creating_thumbnail", "available", "archive"]
759
+ # the status of the layout version
760
+ attribute :status
761
+
762
+ # @!attribute thumbnail_url
763
+ # @return [String, nil] the URL of the thumbnail of the layout version
764
+ attribute :thumbnail_url
765
+
766
+ # @!attribute width
767
+ # @return [Integer] the intended width of the layout version
768
+ attribute :width
723
769
  end
724
770
 
725
771
  # = The player class
@@ -756,8 +802,12 @@ module LWS::DigitalSignage
756
802
  attribute :configuration_id
757
803
 
758
804
  # @!attribute feedbacks
759
- # @return [Array<Player::Feedback>] the feedbacks for the player
760
- has_many :feedbacks, class_name: "LWS::DigitalSignage::Player::Feedback"
805
+ # @return [Hash{String=>String}] a mapping of player feedback key/values
806
+ attribute :feedbacks
807
+
808
+ # @!attribute [r] health_percentage
809
+ # @return [Fixnum] the health of the player (percentage)
810
+ attribute :health_percentage
761
811
 
762
812
  # @!attribute [r] hostname
763
813
  # @return [String] the hostname used by the player (for DHCP for example)
@@ -788,15 +838,27 @@ module LWS::DigitalSignage
788
838
  # @return [Array<Player::Notification>] the notifications for the player
789
839
  has_many :notifications, class_name: "LWS::DigitalSignage::Player::Notification"
790
840
 
791
- # @!attribute operational_since
841
+ # @!attribute operational_hours [r]
842
+ # @return [String, nil] the number of hours the player has been operational
843
+ attribute :operational_hours
844
+
845
+ # @!attribute operational_since [r]
792
846
  # @return [String, nil] the date/time when the player became operational
793
847
  # for the first time
794
848
  attribute :operational_since
795
849
 
850
+ # @!attribute os_release_version
851
+ # @return [String, nil] the OS version the player is using (if known)
852
+ attribute :os_release_version
853
+
796
854
  # @!attribute parts
797
855
  # @return [Array<Player::Component::Part>] the parts of the player
798
856
  has_many :parts, class_name: "LWS::DigitalSignage::Player::Component::Part"
799
857
 
858
+ # @!attribute registration_locked
859
+ # @return [Boolean] whether registarion is locked for the player
860
+ attribute :registration_locked
861
+
800
862
  # @!attribute release_channel
801
863
  # @return [Player::Os::ReleaseChannel] the player OS release channel used
802
864
  # by the player
@@ -809,7 +871,7 @@ module LWS::DigitalSignage
809
871
  attribute :release_channel_id
810
872
 
811
873
  # @!attribute requests
812
- # @return [Array<Player::Feedback>] the requests for the player
874
+ # @return [Array<Player::Request>] the requests for the player
813
875
  has_many :requests, class_name: "LWS::DigitalSignage::Player::Request"
814
876
 
815
877
  # @!attribute screenshots
@@ -824,10 +886,14 @@ module LWS::DigitalSignage
824
886
  # @return [Boolean] whether the player is being serviced/is in service
825
887
  attribute :service
826
888
 
827
- # @!attribute status
889
+ # @!attribute status [r]
828
890
  # @return ["unknown", "good", "warning", "bad"] the player status
829
891
  attribute :status
830
892
 
893
+ # @!attribute status_reason [r]
894
+ # @return [String] the reason for the current player status
895
+ attribute :status_reason
896
+
831
897
  # @!attribute tags
832
898
  # @return [Array<Player::Tag>] the tags of the player
833
899
  has_many :tags, class_name: "LWS::DigitalSignage::Player::Tag"
@@ -978,75 +1044,6 @@ module LWS::DigitalSignage
978
1044
  attribute :value
979
1045
  end
980
1046
 
981
- # = The player feedback class
982
- #
983
- # @note
984
- # This class is only used within the context of the {Player} class.
985
- class Player::Feedback < LWS::Generic::Model
986
- use_api LWS::DigitalSignage.api
987
- uri "players/:player_id/feedbacks(/:id)"
988
-
989
- # @!attribute player
990
- # @return [Player] the player the feedback is originating from
991
- belongs_to :player, class_name: "LWS::DigitalSignage::Player"
992
-
993
- # @!attribute player_id
994
- # @return [Integer] the ID of the player the feedback is originating from
995
- attribute :player_id
996
-
997
- # @!attribute release
998
- # @return [Player::Os::Branch::Release] the player OS branch release the
999
- # feedback is related to
1000
- # FIXME: Missing branch_id field in LWS
1001
- belongs_to :release, class_name: "LWS::DigitalSignage::Player::Os::Branch::Release",
1002
- uri: "player/os/branches/:branch_id/releases/:id"
1003
-
1004
- # @!attribute release_id
1005
- # @return [Integer] the ID of the player OS branch release the feedback
1006
- # is related to
1007
-
1008
- # @!attribute results
1009
- # @return [Array<Player::Feedback::Result>] the results of the player feedback
1010
- # FIXME: Chained associations don't work yet in Spyke (#89)
1011
- has_many :results, class_name: "LWS::DigitalSignage::Player::Feedback::Result",
1012
- uri: "players/:player_id/feedbacks/:feedback_id/results(/:id)"
1013
- end
1014
-
1015
- # = The player feedback result class
1016
- #
1017
- # @note
1018
- # This class is only used within the context of the {Player::Feedback}
1019
- # class.
1020
- class Player::Feedback::Result < LWS::Generic::Model
1021
- use_api LWS::DigitalSignage.api
1022
- uri "players/:player_id/feedbacks/:feedback_id/results(/:id)"
1023
-
1024
- # @!attribute feedback
1025
- # @return [Player::Feedback] the player feedback the result is a part of
1026
- belongs_to :feedback, class_name: "LWS::DigitalSignage::Player::Feedback",
1027
- uri: "players/:player_id/feedbacks/:id"
1028
-
1029
- # @!attribute feedback_id
1030
- # @return [Player::Feedback] the ID of the player feedback the result is a part of
1031
- attribute :feedback_id
1032
-
1033
- # @!attribute key
1034
- # @return [String] the key of the player feedback result
1035
- attribute :key
1036
-
1037
- # @!attribute player
1038
- # @return [Player] the player the feedback result is for
1039
- belongs_to :player, class_name: "LWS::DigitalSignage::Player"
1040
-
1041
- # @!attribute player_id
1042
- # @return [Integer] the ID of the player the feedback result is for
1043
- attribute :player_id
1044
-
1045
- # @!attribute value
1046
- # @return [String] the value of the player feedback result
1047
- attribute :value
1048
- end
1049
-
1050
1047
  # = The player log class
1051
1048
  #
1052
1049
  # @note
@@ -1570,20 +1567,6 @@ module LWS::DigitalSignage
1570
1567
  # @return [String, nil] the optional argument for the player request
1571
1568
  attribute :argument
1572
1569
 
1573
- # @!attribute feedback
1574
- # This field should be set once the action has been processed (see
1575
- # {#processed}) and the action is +"send_feedback"+.
1576
- #
1577
- # @return [Player::Feedback, nil] the player feedback as a response to the
1578
- # action request +"send_status"+
1579
- belongs_to :feedback, class_name: "LWS::DigitalSignage::Player::Feedback",
1580
- uri: "players/:player_id/feedbacks/:id"
1581
-
1582
- # @!attribute feedback_id
1583
- # @return [Integer, nil] the ID of the player feedback as a response to the
1584
- # action request +"send_status"+
1585
- attribute :feedback_id
1586
-
1587
1570
  # @!attribute log
1588
1571
  # This field should be set once the action has been processed (see
1589
1572
  # {#processed}) and the action is +"send_logs"+.
@@ -1693,6 +1676,15 @@ module LWS::DigitalSignage
1693
1676
  # @return [Integer] the ID of the account used for creating the slide
1694
1677
  attribute :account_id
1695
1678
 
1679
+ # @!attribute channels
1680
+ # @return [Array<Channel>] the channels the slide is scheduled on
1681
+ has_many :channels, class_name: "LWS::DigitalSignage::Channel"
1682
+
1683
+ # @!attribute channel_groups
1684
+ # @return [Array<Channel::Group>] the channel group the slide is
1685
+ # scheduled on
1686
+ has_many :channel_groups, class_name: "LWS::DigitalSignage::Channel::Group"
1687
+
1696
1688
  # @!attribute company
1697
1689
  # @return [LWS::Auth::Company] the company the slide belongs to
1698
1690
  belongs_to :company, class_name: "LWS::Auth::Company"
@@ -1721,6 +1713,11 @@ module LWS::DigitalSignage
1721
1713
  # @return [Array<Schedule>] the slide schedules that apply for the slide
1722
1714
  # FIXME: Missing endpoint in LWS
1723
1715
  has_many :schedules, class_name: "LWS::DigitalSignage::Slide::Schedule"
1716
+
1717
+ # @!attribute status [r]
1718
+ # @return ["initializing", "waiting_content", "available", "error"]
1719
+ # the status of the slide
1720
+ attribute :status
1724
1721
  end
1725
1722
 
1726
1723
  # = The slide schedule class
@@ -150,8 +150,9 @@ module LWS::Generic
150
150
  result
151
151
  end
152
152
 
153
- # Extracts a nested attribute vlaue specified by the sequence of attribute names
153
+ # Extracts a nested attribute value specified by the sequence of attribute names
154
154
  # by calling dig at each step, returning +nil+ if any intermediate step is +nil+.
155
+ # @return [Object, nil] the digged up value or +nil+
155
156
  def dig(*attrs)
156
157
  attr = attrs.shift
157
158
  value = send(attr)
@@ -161,6 +162,20 @@ module LWS::Generic
161
162
  value.dig(*attrs)
162
163
  end
163
164
 
165
+ # Returns a deep copy of the model.
166
+ # @return [Model] a deep copy of the model
167
+ def deep_dup
168
+ dup_obj = super
169
+ dup_obj.instance_eval do
170
+ @changed_attributes = @changed_attributes.deep_dup
171
+ @previously_changed = @previously_changed.deep_dup
172
+ @scope = @scope.deep_dup
173
+ @spyke_attributes = @spyke_attributes.deep_dup
174
+ @uri_template = @uri_template.deep_dup
175
+ end
176
+ dup_obj
177
+ end
178
+
164
179
  end
165
180
 
166
181
  # = The configuration class
@@ -180,9 +195,11 @@ module LWS::Generic
180
195
  class Storage
181
196
  # @!visibility private
182
197
  def self.use_api(api)
183
- @connection = Faraday.new(url: api.url_prefix) do |c|
184
- config = LWS.config
198
+ config = LWS.config
185
199
 
200
+ # A connection to Active Storage (with JSON request/response, but without
201
+ # token authentication and caching).
202
+ @as_connection = Faraday.new(url: api.url_prefix) do |c|
186
203
  # Request
187
204
  c.request :json
188
205
 
@@ -197,6 +214,36 @@ module LWS::Generic
197
214
  c.adapter Faraday.default_adapter
198
215
  end
199
216
  end
217
+
218
+ # A plain file connection to LWS (with token autnentication and caching but without
219
+ # JSON request/response).
220
+ @lws_connection = Faraday.new(url: api.url_prefix) do |c|
221
+ # Request
222
+ if config.caching_object
223
+ c.use FaradayMiddleware::Caching, config.caching_object
224
+ end
225
+ c.use LWS::Middleware::RequestHeaders, config.api_token
226
+ c.use config.api_token_middleware if config.api_token_middleware.present?
227
+
228
+ # Response
229
+ c.use FaradayMiddleware::FollowRedirects, limit: 3
230
+ c.use LWS::HTTPLogger, config.logger, config.http_debug_headers if config.http_debug
231
+
232
+ # Adapter
233
+ if config.http_persistent
234
+ c.adapter :net_http_persistent
235
+ else
236
+ c.adapter Faraday.default_adapter
237
+ end
238
+ end
239
+ end
240
+
241
+ # (see .upload)
242
+ # @deprecated
243
+ # To have a consistent upload/download naming counterpart, this
244
+ # method has been deprecated. Use {.upload} instead.
245
+ def self.create(file_or_io, filename, content_type = "application/octet-stream")
246
+ upload(file_or_io, filename, content_type)
200
247
  end
201
248
 
202
249
  # Uploads a file (or IO object) to the storage of the app module.
@@ -208,7 +255,7 @@ module LWS::Generic
208
255
  # @param filename [String] the filename to use for the uploaded file/IO object
209
256
  # @param content_type [String] the content type of the uploaded file/IO object
210
257
  # @return [String, nil] the storage ID (if successful)
211
- def self.create(file_or_io, filename, content_type = "application/octet-stream")
258
+ def self.upload(file_or_io, filename, content_type = "application/octet-stream")
212
259
  return nil if file_or_io.closed?
213
260
 
214
261
  data = file_or_io.read
@@ -217,7 +264,7 @@ module LWS::Generic
217
264
  content_type: content_type,
218
265
  byte_size: data.length,
219
266
  checksum: checksum } }
220
- res = @connection.post do |req|
267
+ res = @as_connection.post do |req|
221
268
  req.url "rails/active_storage/direct_uploads"
222
269
  req.headers["Accept"] = "application/json"
223
270
  req.headers["Content-Type"] = "application/json"
@@ -226,7 +273,7 @@ module LWS::Generic
226
273
 
227
274
  if res.success?
228
275
  result = JSON.parse(res.body)
229
- res = @connection.put do |req|
276
+ res = @as_connection.put do |req|
230
277
  req.url result.dig("direct_upload", "url")
231
278
  result.dig("direct_upload", "headers").each do |hdr, val|
232
279
  req.headers[hdr] = val
@@ -240,6 +287,24 @@ module LWS::Generic
240
287
  nil
241
288
  end
242
289
  end
243
- end
244
290
 
291
+ # Downloads a file at the provided URL from the storage using the
292
+ # appropriate API tokens.
293
+ #
294
+ # This method can be used to download images/assets/etc. from LWS using
295
+ # URLs provided by attributes that end with +_url+.
296
+ # @param url [String] the URL to download the file from
297
+ # @return [String] the contents of the file
298
+ def self.download(url)
299
+ return nil if url.nil?
300
+
301
+ unless url.start_with? @lws_connection.url_prefix.to_s
302
+ raise ArgumentError,
303
+ "URL does not belong to this LWS app (endpoint: #{@lws_connection.url_prefix})"
304
+ end
305
+
306
+ res = @lws_connection.get(url)
307
+ res.body
308
+ end
309
+ end
245
310
  end
@@ -88,6 +88,46 @@ module LWS::Presence
88
88
  attribute :uuid
89
89
  end
90
90
 
91
+ # = The journal (entry) class
92
+ #
93
+ # @note
94
+ # This class is only used within the context of the {Location} class.
95
+ class Journal < LWS::Generic::Model
96
+ use_api LWS::Presence.api
97
+
98
+ # @!attribute check_in
99
+ # @return [String] the timestamp of the check-in of this journal (entry)
100
+ attribute :check_in
101
+
102
+ # @!attribute check_out
103
+ # @return [String, nil] the timestamp of the check out of this journal (entry)
104
+ attribute :check_out
105
+
106
+ # @!attribute company
107
+ # @return [LWS::Auth::Company] the company the journal (entry) belongs to
108
+ belongs_to :company, class_name: "LWS::Auth::Company"
109
+
110
+ # @!attribute company_id
111
+ # @return [Integer] the ID of the company the journal (entry) belongs to
112
+ attribute :company_id
113
+
114
+ # @!attribute location
115
+ # @return [Location] the location the journal (entry) belongs to
116
+ belongs_to :location
117
+
118
+ # @!attribute location_id
119
+ # @return [Integer] the ID of the location the journal (entry) belongs to
120
+ attribute :location_id
121
+
122
+ # @!attribute person
123
+ # @return [Person] the person the journal (entry) belongs to
124
+ belongs_to :person
125
+
126
+ # @!attribute person_id
127
+ # @return [Integer] the ID of the person the journal (entry) belongs to
128
+ attribute :person_id
129
+ end
130
+
91
131
  # = The location class
92
132
  class Location < LWS::Generic::Model
93
133
  use_api LWS::Presence.api
@@ -133,6 +173,14 @@ module LWS::Presence
133
173
  # the presence status to set people to when checking in
134
174
  attribute :checkin_status
135
175
 
176
+ # @!attribute checkout_alter_status
177
+ # @return ["available", "unavailable", "maintenance_cleaning",
178
+ # "maintenance_technical", "permanent_available",
179
+ # "permanent_unavailable", "permanent_maintenance_cleaning",
180
+ # "permanent_maintenance_technical", nil] the status to set the
181
+ # location to when someone checks out
182
+ attribute :checkout_alter_status
183
+
136
184
  # @!attribute checkout_location
137
185
  # @return [Location, nil] the location to move people to when they
138
186
  # are checked out
@@ -157,13 +205,28 @@ module LWS::Presence
157
205
  # @return [Array<Integer>] the IDs of the underlying locations of the location
158
206
  attribute :descendant_ids
159
207
 
208
+ # @!attribute image_storage_id
209
+ # @return [String, nil] the storage ID of the image of the location
210
+ attribute :image_storage_id
211
+
212
+ # @!attribute image_url
213
+ # @note
214
+ # To be able retrieve this, the token needs to be passed via +X-Token+
215
+ # in the HTTP request headers!
216
+ # @return [String, nil] the URL of the image of the location
217
+ attribute :image_url
218
+
219
+ # @!attribute journals
220
+ # @return [Array<Journal>] the journal (entries) associated with the location
221
+ has_many :journals, class: "LWS::Presence::Journal"
222
+
160
223
  # @!attribute lat
161
224
  # @return [Float] the latitude of the location
162
225
  attribute :lat
163
226
 
164
227
  # @!attribute logoff_time
165
- # The format of the time is +HH:MM+ and should be interpreted in the time zone
166
- # of the location (see also {#time_zone}).
228
+ # The format of the time is +HH:MM+ and should be interpreted in the time zone
229
+ # of the location (see also {#time_zone}).
167
230
  # @return [String] the time everybody is automatically logged off
168
231
  attribute :logoff_time
169
232
 
@@ -221,6 +284,13 @@ module LWS::Presence
221
284
  # @return [Array<Reader>] the (RFID/code/ID/...) readers linked to this location
222
285
  has_many :readers
223
286
 
287
+ # @!attribute status
288
+ # @return ["available", "unavailable", "maintenance_cleaning",
289
+ # "maintenance_technical", "permanent_available",
290
+ # "permanent_unavailable", "permanent_maintenance_cleaning",
291
+ # "permanent_maintenance_technical"] the status of the location
292
+ attribute :status
293
+
224
294
  # @!attribute time_zone
225
295
  # @return [String] the time zone of the location
226
296
  attribute :time_zone
@@ -238,6 +308,17 @@ module LWS::Presence
238
308
  use_api LWS::Presence.api
239
309
  uri "locations/:location_id/maps(/:id)"
240
310
 
311
+ # @!attribute image_storage_id
312
+ # @return [String, nil] the storage ID of the image of the map
313
+ attribute :image_storage_id
314
+
315
+ # @!attribute image_url
316
+ # @note
317
+ # To be able retrieve this, the token needs to be passed via +X-Token+
318
+ # in the HTTP request headers!
319
+ # @return [String, nil] the URL of the image of the map
320
+ attribute :image_url
321
+
241
322
  # @!attribute location
242
323
  # @return [Location] the location the map belongs to
243
324
  belongs_to :location
@@ -251,6 +332,9 @@ module LWS::Presence
251
332
  attribute :name
252
333
 
253
334
  # @!attribute picture_url
335
+ # @deprecated
336
+ # Unauthenticated retrieval of the picture will not longer be supported
337
+ # in upcoming releases of LWS. Use {#image_url} instead!
254
338
  # @return [String, nil] the URL of the picture of the map
255
339
  attribute :picture_url
256
340
 
@@ -359,6 +443,17 @@ module LWS::Presence
359
443
  # @return [Array<Appointment>] the appointments involving the person
360
444
  has_many :appointments
361
445
 
446
+ # @!attribute avatar_storage_id
447
+ # @return [String, nil] the storage ID of the avatar of the person
448
+ attribute :avatar_storage_id
449
+
450
+ # @!attribute avatar_url
451
+ # @note
452
+ # To be able retrieve this, the token needs to be passed via +X-Token+
453
+ # in the HTTP request headers!
454
+ # @return [String, nil] the URL of the avatar of the person
455
+ attribute :avatar_url
456
+
362
457
  # @!attribute company
363
458
  # @return [LWS::Auth::Company] the company the person belongs to
364
459
  belongs_to :company, class_name: "LWS::Auth::Company"
@@ -422,6 +517,14 @@ module LWS::Presence
422
517
  # @return [Integer] the ID of the location the person is located at
423
518
  attribute :location_id
424
519
 
520
+ # @!attribute location_status_change_permissions
521
+ # @return [Array<"available", "unavailable", "maintenance_cleaning",
522
+ # "maintenance_technical", "permanent_available",
523
+ # "permanent_unavailable", "permanent_maintenance_cleaning",
524
+ # "permanent_maintenance_technical">] the location statuses the person
525
+ # will clear to available on check-in
526
+ attribute :location_status_change_permissions
527
+
425
528
  # @!attribute long
426
529
  # @return [Float, nil] the exact longitude of the person's location
427
530
  attribute :long
@@ -457,6 +560,9 @@ module LWS::Presence
457
560
  attribute :phone_mobile
458
561
 
459
562
  # @!attribute picture_url
563
+ # @deprecated
564
+ # Unauthenticated retrieval of the picture will not longer be supported
565
+ # in upcoming releases of LWS. Use {#avatar_url} instead!
460
566
  # @return [String, nil] the URL of the picture of the person
461
567
  attribute :picture_url
462
568
 
@@ -512,4 +618,9 @@ module LWS::Presence
512
618
  attribute :node
513
619
  end
514
620
 
621
+ # (see Generic::Storage)
622
+ class Storage < LWS::Generic::Storage
623
+ use_api LWS::Presence.api
624
+ end
625
+
515
626
  end
@@ -108,6 +108,11 @@ module LWS::Resource
108
108
  # @return [String] the URL of a preview of the collection
109
109
  attribute :preview_url
110
110
 
111
+ # @!attribute processing
112
+ # @return [Boolean] whether the collection is being processed (i.e. it is
113
+ # not ready for use)
114
+ attribute :processing
115
+
111
116
  # @!attribute uuid
112
117
  # @return [String] the UUID used for unique file name generation
113
118
  attribute :uuid
@@ -537,6 +542,21 @@ module LWS::Resource
537
542
  # @!attribute parent_id
538
543
  # @return [Integer, nil] the ID of the parent folder of the folder
539
544
  attribute :parent_id
545
+
546
+ # @!attribute permission
547
+ # A UNIX-style permission that indicates whether the folder is shared and
548
+ # who can read/write in it:
549
+ # * 700: not shared (the default), only readable/writable by the
550
+ # associated account
551
+ # * 740: readable by anyone in the company
552
+ # * 770: readable/writeable by anyone in the company
553
+ # @return ["700", "740", "770"] the (share) permission of the folder
554
+ attribute :permission
555
+
556
+ # @!attribute temporary
557
+ # @return [Boolean] whether the folder is temporary and thus will be
558
+ # deleted after some time
559
+ attribute :temporary
540
560
  end
541
561
 
542
562
  end
@@ -13,6 +13,6 @@ module LWS
13
13
 
14
14
  # The LWS library version.
15
15
  # @note The major and minor version parts match the LWS API version!
16
- VERSION = "7.0.1".freeze
16
+ VERSION = "7.1.2".freeze
17
17
 
18
18
  end
@@ -16,7 +16,7 @@ class TestCorporateWebsiteArticle < MiniTest::Test
16
16
  include LWS::CorporateWebsite
17
17
 
18
18
  def setup
19
- @page = Page.all.first
19
+ @page = Page.find(1)
20
20
  @article = @page.articles.first
21
21
  end
22
22
 
@@ -38,7 +38,7 @@ class TestCorporateWebsiteOfficeTime < MiniTest::Test
38
38
  include LWS::CorporateWebsite
39
39
 
40
40
  def setup
41
- @office_time = OfficeTime.all.first
41
+ @office_time = OfficeTime.find(1)
42
42
  end
43
43
 
44
44
  def test_valid
@@ -54,7 +54,7 @@ class TestCorporateWebsitePage < MiniTest::Test
54
54
  include LWS::CorporateWebsite
55
55
 
56
56
  def setup
57
- @page = Page.all.first
57
+ @page = Page.find(1)
58
58
  end
59
59
 
60
60
  def test_valid
@@ -75,7 +75,7 @@ end
75
75
  # include LWS::CorporateWebsite
76
76
  #
77
77
  # def setup
78
- # @social_page = SocialPage.all.first
78
+ # @social_page = SocialPage.find(1)
79
79
  # end
80
80
  #
81
81
  # def test_valid
@@ -96,7 +96,7 @@ class TestCorporateWebsiteSocialPost < MiniTest::Test
96
96
  include LWS::CorporateWebsite
97
97
 
98
98
  def setup
99
- @social_post = SocialPost.all.first
99
+ @social_post = SocialPost.find(1)
100
100
  end
101
101
 
102
102
  def test_valid
@@ -30,6 +30,8 @@ class TestDigitalSignageChannel < MiniTest::Test
30
30
  assert_instance_of(Display, @channel.display)
31
31
  assert_instance_of(Channel::Group, @channel.groups.first)
32
32
  assert_instance_of(Player, @channel.players.first)
33
+ # FIXME: Missing endpoint in LWS
34
+ #assert_instance_of(Slide, @channel.slides.first)
33
35
  assert_instance_of(Channel::Tag, @channel.tags.first)
34
36
  assert_instance_of(Channel::TimeSchedule, @channel.time_schedule)
35
37
  assert_instance_of(Channel::TimeScheduleOverride, @channel.time_schedule_overrides.first)
@@ -55,6 +57,8 @@ class TestDigitalSignageChannelGroup < MiniTest::Test
55
57
  assert_instance_of(Channel, @channel_group.channels.first)
56
58
  assert_instance_of(LWS::Auth::Company, @channel_group.company)
57
59
  assert_instance_of(Channel::Group, @channel_group.parent)
60
+ # FIXME: Missing endpoint in LWS
61
+ #assert_instance_of(Slide, @channel_group.slides.first)
58
62
  assert_instance_of(Channel::Group::Tag, @channel_group.tags.first)
59
63
  assert_instance_of(Channel::TimeScheduleOverride, @channel_group.time_schedule_overrides.first)
60
64
  end
@@ -157,7 +161,7 @@ class TestDigitalSignageChannelTimeScheduleOverride < MiniTest::Test
157
161
  include LWS::DigitalSignage
158
162
 
159
163
  def setup
160
- @channel_time_schedule_override = Channel::TimeScheduleOverride.all.first
164
+ @channel_time_schedule_override = Channel::TimeScheduleOverride.find(1)
161
165
  end
162
166
 
163
167
  def test_valid
@@ -526,64 +530,6 @@ class TestDigitalSignagePlayerConfigurationSetting < MiniTest::Test
526
530
 
527
531
  end
528
532
 
529
- class TestDigitalSignagePlayerFeedback < MiniTest::Test
530
-
531
- include LWS::DigitalSignage
532
-
533
- def setup
534
- @player = Player.find(1)
535
- # Player feedbacks only exist as child objects of players
536
- @player_feedback = @player.feedbacks.first
537
- end
538
-
539
- def test_valid
540
- refute_nil(@player_feedback)
541
- assert_instance_of(Player::Feedback, @player_feedback)
542
- refute_nil(@player_feedback.id)
543
- end
544
-
545
- def test_valid_associations
546
- assert_instance_of(Player, @player_feedback.player)
547
- assert_equal(@player, @player_feedback.player)
548
- # FIXME: Missing branch_id field in LWS
549
- #assert_instance_of(Player::Os::Branch::Release, @player_feedback.release)
550
- # FIXME: Chained associations don't work yet in Spyke (#89)
551
- #assert_instance_of(Player::Feedback::Result, @player_feedback.results.first)
552
- end
553
-
554
- end
555
-
556
- class TestDigitalSignagePlayerFeedbackResult < MiniTest::Test
557
-
558
- include LWS::DigitalSignage
559
-
560
- def setup
561
- @player = Player.find(1)
562
- # Player feedbacks only exist as decendant objects of players
563
- @player_feedback = @player.feedbacks.all.first
564
- # Player feedback results only exist as decendant objects of player
565
- # feedbacks
566
- # FIXME: Chained associations don't work yet in Spyke (#89)
567
- #@player_feedback_result = @player_feedback.results.first
568
- end
569
-
570
- # FIXME: Chained associations don't work yet in Spyke (#89)
571
- #def test_valid
572
- # refute_nil(@player_feedback_result)
573
- # assert_instance_of(Player::Feedback::Result, @player_feedback_result)
574
- # refute_nil(@player_feedback_result.id)
575
- #end
576
-
577
- # FIXME: Chained associations don't work yet in Spyke (#89)
578
- #def test_valid_associations
579
- # assert_instance_of(Player, @player_feedback_result.player)
580
- # assert_equal(@player, @player_feedback_result.player)
581
- # assert_instance_of(Player::Feedback, @player_feedback_result.feedback)
582
- # assert_equal(@player_feedback, @player_feedback_result.feedback)
583
- #end
584
-
585
- end
586
-
587
533
  class TestDigitalSignagePlayerLog < MiniTest::Test
588
534
 
589
535
  include LWS::DigitalSignage
@@ -926,9 +872,7 @@ class TestDigitalSignagePlayerRequest < MiniTest::Test
926
872
  assert_equal(@player, @player_request.player)
927
873
  # FIXME: Chained associations don't work yet in Spyke (#89)
928
874
  #if @player_request.processed
929
- # if @player_request.feedback.present?
930
- # assert_instance_of(Player::Feedback, @player_request.feedback)
931
- # elsif @player_request.log.present?
875
+ # if @player_request.log.present?
932
876
  # assert_instance_of(Player::Log, @player_request.log)
933
877
  # elsif @player_request.screenshot.present?
934
878
  # assert_instance_of(Player::Screenshot, @player_request.screenshot)
@@ -1002,6 +946,8 @@ class TestDigitalSignageSlide < MiniTest::Test
1002
946
 
1003
947
  def test_valid_associations
1004
948
  assert_instance_of(LWS::Auth::Account, @slide.account)
949
+ assert_instance_of(Channel, @slide.channels.first)
950
+ assert_instance_of(Channel::Group, @slide.channel_groups.first)
1005
951
  assert_instance_of(LWS::Auth::Company, @slide.company)
1006
952
  assert_instance_of(Layout, @slide.layout)
1007
953
  end
@@ -17,7 +17,7 @@ class TestGenericModel < MiniTest::Test
17
17
  include LWS::Auth
18
18
 
19
19
  def setup
20
- @configuration = Configuration.all.first
20
+ @configuration = Configuration.find(1)
21
21
  end
22
22
 
23
23
  def test_her_compatibility
@@ -106,6 +106,20 @@ class TestGenericModel < MiniTest::Test
106
106
  end
107
107
  end
108
108
 
109
+ def test_deep_dup
110
+ company = LWS::Auth::Company.find(1)
111
+ company_dup = company.deep_dup
112
+
113
+ # The object itself
114
+ refute_equal(company.object_id, company_dup.object_id)
115
+ # An object as attribute value
116
+ refute_equal(company.address.object_id, company_dup.address.object_id)
117
+ # A related object
118
+ refute_equal(company.contact_person.object_id, company_dup.contact_person.object_id)
119
+ # An item in array of related objects
120
+ refute_equal(company.accounts.first.object_id, company_dup.accounts.first.object_id)
121
+ end
122
+
109
123
  end
110
124
 
111
125
  class TestGenericConfiguration < MiniTest::Test
@@ -114,7 +128,7 @@ class TestGenericConfiguration < MiniTest::Test
114
128
  include LWS::Auth
115
129
 
116
130
  def setup
117
- @configuration = Configuration.all.first
131
+ @configuration = Configuration.find(1)
118
132
  end
119
133
 
120
134
  def test_valid
@@ -128,15 +142,37 @@ end
128
142
  class TestGenericStorage < MiniTest::Test
129
143
 
130
144
  # Generic class needs to be accessed under some kind of app
131
- include LWS::Resource
145
+ include LWS::Presence
132
146
 
133
147
  def test_upload
134
148
  data = StringIO.new("some file contents\n")
149
+ refute_nil(Storage.upload(data, "test.txt", "text/plain"))
150
+
151
+ # Test the deprecated method (for now)
135
152
  refute_nil(Storage.create(data, "test.txt", "text/plain"))
136
153
 
137
154
  # Also test using the default HTTP adapter.
138
155
  reconfigure(http_persistent: false)
139
156
  data = StringIO.new("some more file contents\n")
140
- refute_nil(Storage.create(data, "test2.txt", "text/plain"))
157
+ refute_nil(Storage.upload(data, "test2.txt", "text/plain"))
158
+ end
159
+
160
+ def test_download
161
+ location = Location.find(1)
162
+ refute_nil(location.image_url)
163
+
164
+ data = Storage.download(location.image_url)
165
+ assert(data.size > 0)
166
+
167
+ assert_nil(Storage.download(nil))
168
+
169
+ assert_raises(ArgumentError) do
170
+ Storage.download("https://doesnot.exist.tld/some/file")
171
+ end
172
+
173
+ # Also test using the default HTTP adapter.
174
+ reconfigure(http_persistent: false)
175
+ data = Storage.download(location.image_url)
176
+ assert(data.size > 0)
141
177
  end
142
178
  end
@@ -16,7 +16,7 @@ class TestMapsMap < MiniTest::Test
16
16
  include LWS::Maps
17
17
 
18
18
  def setup
19
- @map = Map.all.first
19
+ @map = Map.find(1)
20
20
  end
21
21
 
22
22
  def test_valid_map
@@ -37,7 +37,7 @@ class TestMapsMarker < MiniTest::Test
37
37
  include LWS::Maps
38
38
 
39
39
  def setup
40
- @map = Map.all.first
40
+ @map = Map.find(1)
41
41
  # Markers only exist as child objects of maps
42
42
  @marker = @map.markers.first
43
43
  end
@@ -60,7 +60,7 @@ class TestMapsSource < MiniTest::Test
60
60
  include LWS::Maps
61
61
 
62
62
  def setup
63
- @source = Source.all.first
63
+ @source = Source.find(1)
64
64
  end
65
65
 
66
66
  def test_valid_source
@@ -35,6 +35,29 @@ class TestPresenceAppointment < MiniTest::Test
35
35
 
36
36
  end
37
37
 
38
+ class TestPresenceJournal < MiniTest::Test
39
+ include LWS::Presence
40
+
41
+ def setup
42
+ @location = Location.find(1)
43
+ # Journals only exist as child objects of a location
44
+ @journal = @location.journals.first
45
+ end
46
+
47
+ def test_valid
48
+ refute_nil(@journal)
49
+ assert_instance_of(Journal, @journal)
50
+ refute_nil(@journal.id)
51
+ end
52
+
53
+ def test_valid_associations
54
+ assert_instance_of(LWS::Auth::Company, @journal.company)
55
+ assert_instance_of(Location, @journal.location)
56
+ assert_equal(@location, @journal.location)
57
+ assert_instance_of(Person, @journal.person)
58
+ end
59
+ end
60
+
38
61
  class TestPresenceLocation < MiniTest::Test
39
62
 
40
63
  include LWS::Presence
@@ -165,7 +188,7 @@ class TestPresenceReader < MiniTest::Test
165
188
  include LWS::Presence
166
189
 
167
190
  def setup
168
- @reader = Reader.all.first
191
+ @reader = Reader.find(1)
169
192
  end
170
193
 
171
194
  def test_valid
@@ -25,7 +25,7 @@ class TestResourceCollection < MiniTest::Test
25
25
  include LWS::Resource
26
26
 
27
27
  def setup
28
- @collection = Collection.all.first # FIXME
28
+ @collection = Collection.find(1)
29
29
  end
30
30
 
31
31
  def test_valid
@@ -48,7 +48,7 @@ class TestResourceCollectionItem < MiniTest::Test
48
48
  include LWS::Resource
49
49
 
50
50
  def setup
51
- @collection = Collection.where(includes: "items").first # FIXME
51
+ @collection = Collection.where(includes: "items").find(1)
52
52
  @collection_item = @collection.items.first
53
53
  end
54
54
 
@@ -70,7 +70,7 @@ class TestResourceFolder < MiniTest::Test
70
70
  include LWS::Resource
71
71
 
72
72
  def setup
73
- @folder = Folder.all.first
73
+ @folder = Folder.find(1)
74
74
  end
75
75
 
76
76
  def test_valid
@@ -23,7 +23,7 @@ SimpleCov.at_exit do
23
23
  result.format!
24
24
  simplecov_test_suites = ['minitest']
25
25
  parallel_offset = ENV['PARALLEL_TEST_GROUPS'] ? ENV['PARALLEL_TEST_GROUPS'].to_i - 1 : 0
26
- minimum_coverage = 97
26
+ minimum_coverage = 95
27
27
  # Count the number of commas in the command name to figure out how many result groups were combined into this result
28
28
  if result.command_name.scan(/,/).size + 1 >= simplecov_test_suites.size + (parallel_offset * 2) # two parallel suites
29
29
  # We only want to enforce minimum coverage after all test suites finish
@@ -40,7 +40,7 @@ class TestTicketGroup < MiniTest::Test
40
40
  include LWS::Ticket
41
41
 
42
42
  def setup
43
- @group = Group.all.first
43
+ @group = Group.find(1)
44
44
  end
45
45
 
46
46
  def test_valid
@@ -88,7 +88,7 @@ class TestTicketTag < MiniTest::Test
88
88
  include LWS::Ticket
89
89
 
90
90
  def setup
91
- @tag = Tag.all.first
91
+ @tag = Tag.find(1)
92
92
  end
93
93
 
94
94
  def test_valid_tag
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lws
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.1
4
+ version: 7.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - LeftClick B.V.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-10 00:00:00.000000000 Z
11
+ date: 2020-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday_middleware
@@ -296,27 +296,27 @@ signing_key:
296
296
  specification_version: 4
297
297
  summary: LeftClick web services library for Ruby
298
298
  test_files:
299
+ - test/presence_test.rb
300
+ - test/fixtures/permissions.yml
301
+ - test/fixtures/auth.yml
302
+ - test/corporate_website_test.rb
303
+ - test/logger_test.rb
299
304
  - test/support/with_env.rb
300
- - test/json_parser_test.rb
301
- - test/test_helper.rb
302
- - test/setup_test.rb
303
- - test/ticket_test.rb
304
- - test/api_token_middleware_test.rb
305
305
  - test/stubbing_test.rb
306
- - test/presence_test.rb
306
+ - test/ticket_test.rb
307
307
  - test/digital_signage_test.rb
308
- - test/generic_test.rb
309
- - test/logger_test.rb
308
+ - test/caching_test.rb
310
309
  - test/auth_test.rb
311
- - test/resource_test.rb
312
310
  - test/maps_test.rb
313
- - test/corporate_website_test.rb
314
- - test/config/tokens.yml
315
- - test/config/empty.yml
311
+ - test/json_parser_test.rb
312
+ - test/resource_test.rb
316
313
  - test/config/endpoints.yml
317
- - test/config/invalid.yml
318
314
  - test/config/switch_env.yml
315
+ - test/config/invalid.yml
316
+ - test/config/empty.yml
317
+ - test/config/tokens.yml
319
318
  - test/config/full.yml
320
- - test/caching_test.rb
321
- - test/fixtures/auth.yml
322
- - test/fixtures/permissions.yml
319
+ - test/setup_test.rb
320
+ - test/api_token_middleware_test.rb
321
+ - test/generic_test.rb
322
+ - test/test_helper.rb