lws 7.0.0 → 7.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: dc635406b8325652b128c7214d332b1686fbd4ba0fee74bc4c8716d75d3a349a
4
- data.tar.gz: 93953a65dec58a2a509866b4f0252d2c7e4a68227e09258f3376d946c5503ae6
3
+ metadata.gz: 71a8d517993d1edc2f3ee98d57c5e8d96722e8c30f3022e346eaeee1f548a8b8
4
+ data.tar.gz: ca21b87824d2470ebfde323df4e979be95ca943d79df42ab454d66626ab50532
5
5
  SHA512:
6
- metadata.gz: 65fe4cc5990944a1512cbcd73868b76268f5fdc937ae5de344e57a7a4a5f05abe38256bc4d8d057a0e505871caa9f45dceb3fd859e9616a61afed5b3853c29fd
7
- data.tar.gz: 60bba2e6c25ad035deb2193dc93cc9f3553364ea9bf7b0997e19f422ce5e8575118c143a7cf7862ce96b4dd47d515b0c46b17d2cb398a5f5d0328f26f119c96e
6
+ metadata.gz: 0bc0ba9e36161be2702592791d1c4baad190714b39fe5fe67e2e0b78c61cf80e5a53be2ce3d820497052b87e587f5efdfd0253fd4561f97debabfd961fb8b0d5
7
+ data.tar.gz: 6db01df5b9610858c985e4d1ab711cf29538a9bed8601437a7f476c3d633417ed910a93ed0b32b3ed9d88a7d993667f2ae8a03689c4afd4e4e959cbc417cdee2
@@ -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",
@@ -512,6 +524,10 @@ module LWS::DigitalSignage
512
524
  # @return [Boolean] whether the layout is a favorite for the current account
513
525
  attribute :favorite
514
526
 
527
+ # @!attribute kind
528
+ # @return ["marquee", "slide"] the kind of the layout
529
+ attribute :kind
530
+
515
531
  # @!attribute name
516
532
  # @return [String] the name of the layout
517
533
  attribute :name
@@ -575,6 +591,10 @@ module LWS::DigitalSignage
575
591
  # @!attribute name
576
592
  # @return [String] the name of the layout category
577
593
  attribute :name
594
+
595
+ # @!attribute translated_name
596
+ # @return [String] the translated name of the layout category
597
+ attribute :name
578
598
  end
579
599
 
580
600
  # = The layout element class
@@ -624,6 +644,10 @@ module LWS::DigitalSignage
624
644
  # element
625
645
  has_many :properties, class_name: "LWS::DigitalSignage::Layout::Element::Property"
626
646
 
647
+ # @!attribute title
648
+ # @return [String, nil] the title of the layout element
649
+ attribute :title
650
+
627
651
  # @!attribute version
628
652
  # @return [Layout::Verion] the layout version that contains the element
629
653
  # FIXME: Missing endpoint in LWS
@@ -709,6 +733,10 @@ module LWS::DigitalSignage
709
733
  # version
710
734
  has_many :elements, class_name: "LWS::DigitalSignage::Layout::Element"
711
735
 
736
+ # @!attribute height
737
+ # @return [Integer] the intended height of the layout version
738
+ attribute :width
739
+
712
740
  # @!attribute layout
713
741
  # @return [Layout] the layout the layout version is for
714
742
  belongs_to :layout
@@ -716,6 +744,28 @@ module LWS::DigitalSignage
716
744
  # @!attribute layout_id
717
745
  # @return [Integer] the ID of the layout the layout version is for
718
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
719
769
  end
720
770
 
721
771
  # = The player class
@@ -752,8 +802,16 @@ module LWS::DigitalSignage
752
802
  attribute :configuration_id
753
803
 
754
804
  # @!attribute feedbacks
755
- # @return [Array<Player::Feedback>] the feedbacks for the player
756
- 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
811
+
812
+ # @!attribute [r] hostname
813
+ # @return [String] the hostname used by the player (for DHCP for example)
814
+ attribute :hostname
757
815
 
758
816
  # @!attribute logs
759
817
  # @return [Array<Player::Log>] the logs of the player
@@ -770,7 +828,7 @@ module LWS::DigitalSignage
770
828
  # @!attribute model
771
829
  # @return [Player::Model] the model of the player
772
830
  belongs_to :model, class_name: "LWS::DigitalSignage::Player::Model",
773
- uri: "player/models/:id"
831
+ uri: "player/models/:id"
774
832
 
775
833
  # @!attribute model_id
776
834
  # @return [Integer] the ID of the model of the player
@@ -780,15 +838,27 @@ module LWS::DigitalSignage
780
838
  # @return [Array<Player::Notification>] the notifications for the player
781
839
  has_many :notifications, class_name: "LWS::DigitalSignage::Player::Notification"
782
840
 
783
- # @!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]
784
846
  # @return [String, nil] the date/time when the player became operational
785
847
  # for the first time
786
848
  attribute :operational_since
787
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
+
788
854
  # @!attribute parts
789
855
  # @return [Array<Player::Component::Part>] the parts of the player
790
856
  has_many :parts, class_name: "LWS::DigitalSignage::Player::Component::Part"
791
857
 
858
+ # @!attribute registration_locked
859
+ # @return [Boolean] whether registarion is locked for the player
860
+ attribute :registration_locked
861
+
792
862
  # @!attribute release_channel
793
863
  # @return [Player::Os::ReleaseChannel] the player OS release channel used
794
864
  # by the player
@@ -801,7 +871,7 @@ module LWS::DigitalSignage
801
871
  attribute :release_channel_id
802
872
 
803
873
  # @!attribute requests
804
- # @return [Array<Player::Feedback>] the requests for the player
874
+ # @return [Array<Player::Request>] the requests for the player
805
875
  has_many :requests, class_name: "LWS::DigitalSignage::Player::Request"
806
876
 
807
877
  # @!attribute screenshots
@@ -816,10 +886,14 @@ module LWS::DigitalSignage
816
886
  # @return [Boolean] whether the player is being serviced/is in service
817
887
  attribute :service
818
888
 
819
- # @!attribute status
889
+ # @!attribute status [r]
820
890
  # @return ["unknown", "good", "warning", "bad"] the player status
821
891
  attribute :status
822
892
 
893
+ # @!attribute status_reason [r]
894
+ # @return [String] the reason for the current player status
895
+ attribute :status_reason
896
+
823
897
  # @!attribute tags
824
898
  # @return [Array<Player::Tag>] the tags of the player
825
899
  has_many :tags, class_name: "LWS::DigitalSignage::Player::Tag"
@@ -970,75 +1044,6 @@ module LWS::DigitalSignage
970
1044
  attribute :value
971
1045
  end
972
1046
 
973
- # = The player feedback class
974
- #
975
- # @note
976
- # This class is only used within the context of the {Player} class.
977
- class Player::Feedback < LWS::Generic::Model
978
- use_api LWS::DigitalSignage.api
979
- uri "players/:player_id/feedbacks(/:id)"
980
-
981
- # @!attribute player
982
- # @return [Player] the player the feedback is originating from
983
- belongs_to :player, class_name: "LWS::DigitalSignage::Player"
984
-
985
- # @!attribute player_id
986
- # @return [Integer] the ID of the player the feedback is originating from
987
- attribute :player_id
988
-
989
- # @!attribute release
990
- # @return [Player::Os::Branch::Release] the player OS branch release the
991
- # feedback is related to
992
- # FIXME: Missing branch_id field in LWS
993
- belongs_to :release, class_name: "LWS::DigitalSignage::Player::Os::Branch::Release",
994
- uri: "player/os/branches/:branch_id/releases/:id"
995
-
996
- # @!attribute release_id
997
- # @return [Integer] the ID of the player OS branch release the feedback
998
- # is related to
999
-
1000
- # @!attribute results
1001
- # @return [Array<Player::Feedback::Result>] the results of the player feedback
1002
- # FIXME: Chained associations don't work yet in Spyke (#89)
1003
- has_many :results, class_name: "LWS::DigitalSignage::Player::Feedback::Result",
1004
- uri: "players/:player_id/feedbacks/:feedback_id/results(/:id)"
1005
- end
1006
-
1007
- # = The player feedback result class
1008
- #
1009
- # @note
1010
- # This class is only used within the context of the {Player::Feedback}
1011
- # class.
1012
- class Player::Feedback::Result < LWS::Generic::Model
1013
- use_api LWS::DigitalSignage.api
1014
- uri "players/:player_id/feedbacks/:feedback_id/results(/:id)"
1015
-
1016
- # @!attribute feedback
1017
- # @return [Player::Feedback] the player feedback the result is a part of
1018
- belongs_to :feedback, class_name: "LWS::DigitalSignage::Player::Feedback",
1019
- uri: "players/:player_id/feedbacks/:id"
1020
-
1021
- # @!attribute feedback_id
1022
- # @return [Player::Feedback] the ID of the player feedback the result is a part of
1023
- attribute :feedback_id
1024
-
1025
- # @!attribute key
1026
- # @return [String] the key of the player feedback result
1027
- attribute :key
1028
-
1029
- # @!attribute player
1030
- # @return [Player] the player the feedback result is for
1031
- belongs_to :player, class_name: "LWS::DigitalSignage::Player"
1032
-
1033
- # @!attribute player_id
1034
- # @return [Integer] the ID of the player the feedback result is for
1035
- attribute :player_id
1036
-
1037
- # @!attribute value
1038
- # @return [String] the value of the player feedback result
1039
- attribute :value
1040
- end
1041
-
1042
1047
  # = The player log class
1043
1048
  #
1044
1049
  # @note
@@ -1562,20 +1567,6 @@ module LWS::DigitalSignage
1562
1567
  # @return [String, nil] the optional argument for the player request
1563
1568
  attribute :argument
1564
1569
 
1565
- # @!attribute feedback
1566
- # This field should be set once the action has been processed (see
1567
- # {#processed}) and the action is +"send_feedback"+.
1568
- #
1569
- # @return [Player::Feedback, nil] the player feedback as a response to the
1570
- # action request +"send_status"+
1571
- belongs_to :feedback, class_name: "LWS::DigitalSignage::Player::Feedback",
1572
- uri: "players/:player_id/feedbacks/:id"
1573
-
1574
- # @!attribute feedback_id
1575
- # @return [Integer, nil] the ID of the player feedback as a response to the
1576
- # action request +"send_status"+
1577
- attribute :feedback_id
1578
-
1579
1570
  # @!attribute log
1580
1571
  # This field should be set once the action has been processed (see
1581
1572
  # {#processed}) and the action is +"send_logs"+.
@@ -1685,6 +1676,15 @@ module LWS::DigitalSignage
1685
1676
  # @return [Integer] the ID of the account used for creating the slide
1686
1677
  attribute :account_id
1687
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
+
1688
1688
  # @!attribute company
1689
1689
  # @return [LWS::Auth::Company] the company the slide belongs to
1690
1690
  belongs_to :company, class_name: "LWS::Auth::Company"
@@ -1713,6 +1713,11 @@ module LWS::DigitalSignage
1713
1713
  # @return [Array<Schedule>] the slide schedules that apply for the slide
1714
1714
  # FIXME: Missing endpoint in LWS
1715
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
1716
1721
  end
1717
1722
 
1718
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
@@ -129,10 +129,18 @@ module LWS::Presence
129
129
  attribute :capacity_used_precentage_tree
130
130
 
131
131
  # @!attribute checkin_status
132
- # @return ["available", "busy", "away", "disabled", nil]
132
+ # @return ["available", "busy", "away", nil]
133
133
  # the presence status to set people to when checking in
134
134
  attribute :checkin_status
135
135
 
136
+ # @!attribute checkout_alter_status
137
+ # @return ["available", "unavailable", "maintenance_cleaning",
138
+ # "maintenance_technical", "permanent_available",
139
+ # "permanent_unavailable", "permanent_maintenance_cleaning",
140
+ # "permanent_maintenance_technical", nil] the status to set the
141
+ # location to when someone checks out
142
+ attribute :checkout_alter_status
143
+
136
144
  # @!attribute checkout_location
137
145
  # @return [Location, nil] the location to move people to when they
138
146
  # are checked out
@@ -157,13 +165,24 @@ module LWS::Presence
157
165
  # @return [Array<Integer>] the IDs of the underlying locations of the location
158
166
  attribute :descendant_ids
159
167
 
168
+ # @!attribute image_storage_id
169
+ # @return [String, nil] the storage ID of the image of the location
170
+ attribute :image_storage_id
171
+
172
+ # @!attribute image_url
173
+ # @note
174
+ # To be able retrieve this, the token needs to be passed via +X-Token+
175
+ # in the HTTP request headers!
176
+ # @return [String, nil] the URL of the image of the location
177
+ attribute :image_url
178
+
160
179
  # @!attribute lat
161
180
  # @return [Float] the latitude of the location
162
181
  attribute :lat
163
182
 
164
183
  # @!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}).
184
+ # The format of the time is +HH:MM+ and should be interpreted in the time zone
185
+ # of the location (see also {#time_zone}).
167
186
  # @return [String] the time everybody is automatically logged off
168
187
  attribute :logoff_time
169
188
 
@@ -221,6 +240,13 @@ module LWS::Presence
221
240
  # @return [Array<Reader>] the (RFID/code/ID/...) readers linked to this location
222
241
  has_many :readers
223
242
 
243
+ # @!attribute status
244
+ # @return ["available", "unavailable", "maintenance_cleaning",
245
+ # "maintenance_technical", "permanent_available",
246
+ # "permanent_unavailable", "permanent_maintenance_cleaning",
247
+ # "permanent_maintenance_technical"] the status of the location
248
+ attribute :status
249
+
224
250
  # @!attribute time_zone
225
251
  # @return [String] the time zone of the location
226
252
  attribute :time_zone
@@ -238,6 +264,17 @@ module LWS::Presence
238
264
  use_api LWS::Presence.api
239
265
  uri "locations/:location_id/maps(/:id)"
240
266
 
267
+ # @!attribute image_storage_id
268
+ # @return [String, nil] the storage ID of the image of the map
269
+ attribute :image_storage_id
270
+
271
+ # @!attribute image_url
272
+ # @note
273
+ # To be able retrieve this, the token needs to be passed via +X-Token+
274
+ # in the HTTP request headers!
275
+ # @return [String, nil] the URL of the image of the map
276
+ attribute :image_url
277
+
241
278
  # @!attribute location
242
279
  # @return [Location] the location the map belongs to
243
280
  belongs_to :location
@@ -251,6 +288,9 @@ module LWS::Presence
251
288
  attribute :name
252
289
 
253
290
  # @!attribute picture_url
291
+ # @deprecated
292
+ # Unauthenticated retrieval of the picture will not longer be supported
293
+ # in upcoming releases of LWS. Use {#image_url} instead!
254
294
  # @return [String, nil] the URL of the picture of the map
255
295
  attribute :picture_url
256
296
 
@@ -359,6 +399,17 @@ module LWS::Presence
359
399
  # @return [Array<Appointment>] the appointments involving the person
360
400
  has_many :appointments
361
401
 
402
+ # @!attribute avatar_storage_id
403
+ # @return [String, nil] the storage ID of the avatar of the person
404
+ attribute :avatar_storage_id
405
+
406
+ # @!attribute avatar_url
407
+ # @note
408
+ # To be able retrieve this, the token needs to be passed via +X-Token+
409
+ # in the HTTP request headers!
410
+ # @return [String, nil] the URL of the avatar of the person
411
+ attribute :avatar_url
412
+
362
413
  # @!attribute company
363
414
  # @return [LWS::Auth::Company] the company the person belongs to
364
415
  belongs_to :company, class_name: "LWS::Auth::Company"
@@ -422,6 +473,14 @@ module LWS::Presence
422
473
  # @return [Integer] the ID of the location the person is located at
423
474
  attribute :location_id
424
475
 
476
+ # @!attribute location_status_change_permissions
477
+ # @return [Array<"available", "unavailable", "maintenance_cleaning",
478
+ # "maintenance_technical", "permanent_available",
479
+ # "permanent_unavailable", "permanent_maintenance_cleaning",
480
+ # "permanent_maintenance_technical">] the location statuses the person
481
+ # will clear to available on check-in
482
+ attribute :location_status_change_permissions
483
+
425
484
  # @!attribute long
426
485
  # @return [Float, nil] the exact longitude of the person's location
427
486
  attribute :long
@@ -457,6 +516,9 @@ module LWS::Presence
457
516
  attribute :phone_mobile
458
517
 
459
518
  # @!attribute picture_url
519
+ # @deprecated
520
+ # Unauthenticated retrieval of the picture will not longer be supported
521
+ # in upcoming releases of LWS. Use {#avatar_url} instead!
460
522
  # @return [String, nil] the URL of the picture of the person
461
523
  attribute :picture_url
462
524
 
@@ -512,4 +574,9 @@ module LWS::Presence
512
574
  attribute :node
513
575
  end
514
576
 
577
+ # (see Generic::Storage)
578
+ class Storage < LWS::Generic::Storage
579
+ use_api LWS::Presence.api
580
+ end
581
+
515
582
  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.0".freeze
16
+ VERSION = "7.1.1".freeze
17
17
 
18
18
  end
@@ -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
@@ -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
@@ -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
@@ -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
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.0
4
+ version: 7.1.1
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-03 00:00:00.000000000 Z
11
+ date: 2020-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday_middleware