lws 7.0.1 → 7.1.2

Sign up to get free protection for your applications and to get access to all the features.
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