lws 6.2.3 → 6.3.0

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: 19a64229c67667d2f4be7cc06ef40cdb06433cb71ccea6699dadc9c288ce0ab2
4
- data.tar.gz: fe728933b84bd16634c2bff02b6633897708d28def2bd5c2d66e069bab0de5c1
3
+ metadata.gz: b78881916d363dc9fed830e0be6cecacc6b3928e699b047cb6004eab310f4ec8
4
+ data.tar.gz: 6de69f0e6437aeaf85cd1bdc1f6527a09cc0e9b33d200b377fb232ea932aa1b0
5
5
  SHA512:
6
- metadata.gz: 83a4ae6fa730a5039dcd360276c3c94e85d34b884f8ce16343ce7a18ea65e3c583efc1574610cdd5152d8a1e0e4c8a6cc3e3818b0aa3811f55769478915d1833
7
- data.tar.gz: 432272f9aae23ca1925a3ac1e2546146dcab56391808bcfd6fe625a6efb996b0449c72bf7fdce962b663e87007b26f97afc7cccdf346c413cc5fb0559f99f983
6
+ metadata.gz: 4f18155b4bf72c6572c9d2dac80d1bc2ad00b35bde4a4169806495fdd4deead5971d7da9c6b7954a7ec859d48a7ac067dfad71d1d8d92c79d557be760a90e2ce
7
+ data.tar.gz: a4935986105ecdf15dd71a6dc33b4b2d40ce5d14363eec241e87cef28904a3db94a542cbe37b9c1cd54955f6c5df60b49d83f11195fb733c414ea3c5ee084251
data/CHANGELOG.md CHANGED
@@ -1,15 +1,30 @@
1
1
  # LeftClick Web Services Changelog
2
2
 
3
- Up until v6.1.0, we used the standard Gem version numbering starting at v0.0.1.
4
- From v6.1.0 on the version will follow the API version of LWS in the major/minor
5
- part of te version.
3
+ Up until version 6.1.0, we used the standard Gem version numbering starting at
4
+ version 0.0.1. From version 6.1.0 on the version will follow the API version
5
+ of LWS in the major/minor part of te version.
6
+
7
+ The changelog follows the [Keep a Changelog] format from version 6.3.0 on.
8
+
9
+ ## [6.3.0] - 2019-09-05
10
+ ### Added
11
+ * Added slide, layout and related models to the DigitalSignage app (#12103)
12
+ * Added the `Storage` class to the DigitalSignage and Resource apps
13
+
14
+ ### Changed
15
+ * All non-persisted objects are always saved (even without changes)
16
+
17
+ ### Fixed
18
+ * Fixed typos in documentation
19
+ * Fixed some code style issues
20
+ * Default to an empty object if the API provides no data
6
21
 
7
22
  ## v6.2.3
8
23
 
9
24
  * Move common attributes to the generic model and add `url`/`url_html` (#12004)
10
25
  * Add password expiration attributes to the `Company` and `User` model of
11
- the Auth app
12
- * Add new attributes to the `Collection` model of the Resource app
26
+ the Auth app (#12012)
27
+ * Add new attributes to the `Collection` model of the Resource app (#12012)
13
28
 
14
29
  ## v6.2.2.1
15
30
 
@@ -122,3 +137,6 @@ part of te version.
122
137
  ## v0.0.1
123
138
 
124
139
  Initial release
140
+
141
+ [Keep a Changelog]: https://keepachangelog.com/en/1.0.0/
142
+ [6.3.0]: https://gitlab.leftclick.eu/platform/ruby-lws/compare/v6.2.3...v6.3.0
data/README.md CHANGED
@@ -97,7 +97,7 @@ arguments. It uses the production environment per default using the token
97
97
  provided by a command-line argument. These defaults can be overriden using
98
98
  the configuration. For example, to rename a map:
99
99
 
100
- ```
100
+ ```sh
101
101
  $ lwsconsole -t "my_token" -a maps
102
102
  [1] lwsconsole(LWS::Maps)> Map.all.map(&:name)
103
103
  => ["Gebouw 1",
data/lib/lws.rb CHANGED
@@ -38,7 +38,7 @@ module LWS
38
38
  # The list of supported apps (web service libraries) loaded by
39
39
  # {.setup}.
40
40
  SUPPORTED_APPS = [:generic, :auth, :corporate_website, :digital_signage,
41
- :maps, :presence, :resource, :ticket]
41
+ :maps, :presence, :resource, :ticket].freeze
42
42
 
43
43
  # @return [Config] the API configuration for the web services
44
44
  mattr_reader :config
@@ -33,6 +33,11 @@ module LWS::DigitalSignage
33
33
  use_api LWS::DigitalSignage.api
34
34
  end
35
35
 
36
+ # (see Generic::Storage)
37
+ class Storage < LWS::Generic::Storage
38
+ use_api LWS::DigitalSignage.api
39
+ end
40
+
36
41
  ### App specific classes
37
42
 
38
43
  # = The channel class
@@ -60,7 +65,7 @@ module LWS::DigitalSignage
60
65
  belongs_to :display, class_name: "LWS::DigitalSignage::Display"
61
66
  # :nocov:
62
67
  def display
63
- # Create a dummy method so that the original #display method is not used
68
+ # Create a dummy method so that the original #display method is not used
64
69
  association(:display).load
65
70
  end
66
71
  # :nocov:
@@ -147,7 +152,7 @@ module LWS::DigitalSignage
147
152
  # @!attribute parent
148
153
  # @return [Channel::Group, nil] the parent group of the channel group
149
154
  belongs_to :parent, class_name: "LWS::DigitalSignage::Channel::Group",
150
- foreign_key: "parent_id",
155
+ foreign_key: :parent_id,
151
156
  uri: "channel/groups/:id"
152
157
 
153
158
  # @!attribute parent_id
@@ -417,7 +422,7 @@ module LWS::DigitalSignage
417
422
  belongs_to :display, class_name: "LWS::DigitalSignage::Display"
418
423
  # :nocov:
419
424
  def display
420
- # Create a dummy method so that the original #display method is not used
425
+ # Create a dummy method so that the original #display method is not used
421
426
  association(:display).load
422
427
  end
423
428
  # :nocov:
@@ -447,7 +452,7 @@ module LWS::DigitalSignage
447
452
  # @!attribute aspect_ratio [r]
448
453
  # The aspect ratio is recalculated immediately when the width and/or
449
454
  # height of the resolution changes.
450
- #
455
+ #
451
456
  # @return [String] the aspect ratio of the resolution
452
457
  attribute :aspect_ratio
453
458
 
@@ -476,6 +481,317 @@ module LWS::DigitalSignage
476
481
  attribute :width
477
482
  end
478
483
 
484
+ # = The layout class
485
+ class Layout < LWS::Generic::Model
486
+ use_api LWS::DigitalSignage.api
487
+
488
+ # @!attribute id [r]
489
+ # @return [Integer] the (unique) ID of the layout
490
+ attribute :id
491
+
492
+ # @!attribute categories
493
+ # @return [Array<Layout::Category>] the categories associated with
494
+ # the layout
495
+ # FIXME: Missing endpoint in LWS
496
+ has_many :categories, class_name: "LWS::DigitalSignage::Layout::Category",
497
+ uri: "layout/:layout_id/categories(/:id)"
498
+
499
+ # @!attribute company
500
+ # @return [LWS::Auth::Company] the company the layout belongs to
501
+ belongs_to :company, class_name: "LWS::Auth::Company"
502
+
503
+ # @!attribute company_id
504
+ # @return [Integer] the ID of the company the layout belongs to
505
+ attribute :company_id
506
+
507
+ # @!attribute default_duration
508
+ # @return [5..3600] the default duration of a slide created from the layout
509
+ attribute :default_duration
510
+
511
+ # @!attribute description
512
+ # @return [String, nil] the description of the layout
513
+ attribute :description
514
+
515
+ # @!attribute favorite
516
+ # @return [Boolean] whether the layout is a favorite for the current account
517
+ attribute :favorite
518
+
519
+ # @!attribute name
520
+ # @return [String] the name of the layout
521
+ attribute :name
522
+
523
+ # @!attribute parent
524
+ # @return [Layout, nil] the parent of the layout
525
+ # FIXME: Missing parent_id field in LWS
526
+ belongs_to :parent, class_name: "LWS::DigitalSignage::Layout",
527
+ foreign_key: :parent_id,
528
+ uri: "layouts/:id"
529
+
530
+ # @!attribute parent_id
531
+ # @return [Integer, nil] the ID of the parent of the layout
532
+ attribute :parent_id
533
+
534
+ # @!attribute priority
535
+ # @return [Boolean] whether the layout has priority over others
536
+ attribute :priority
537
+
538
+ # @!attribute slides
539
+ # @return [Array<Slide>] the slides using the layout
540
+ has_many :slides, class_name: "LWS::DigitalSignage::Slide",
541
+ uri: "layouts/:layout_id/slides(/:id)"
542
+
543
+ # @!attribute trans
544
+ # @return ["cut", "fadein", "zoomin", "slidein"] the transition of the
545
+ # entire layout
546
+ attribute :trans
547
+
548
+ # @!attribute trans_direction
549
+ # @return ["left", "right", "up", "down"] the direction of the transition
550
+ # of the entire layout
551
+ attribute :trans_direction
552
+
553
+ # @!attribute trans_duration
554
+ # @return [Integer] the duration of the transition of the entire layout
555
+ attribute :trans_duration
556
+
557
+ # @!attribute versions
558
+ # @return [Array<Version>] the versions of the layout
559
+ has_many :versions, class_name: "LWS::DigitalSignage::Layout::Version",
560
+ uri: "layouts/:layout_id/versions(/:id)"
561
+
562
+ # @!attribute created_at [r]
563
+ # @return [String] the timestamp of when the layout was created
564
+ attribute :created_at
565
+
566
+ # @!attribute updated_at [r]
567
+ # @return [String] the timestamp of when the layout was last updated
568
+ attribute :updated_at
569
+ end
570
+
571
+ # = The layout category class
572
+ class Layout::Category < LWS::Generic::Model
573
+ use_api LWS::DigitalSignage.api
574
+ uri "layout/categories(/:id)"
575
+
576
+ # @!attribute id [r]
577
+ # @return [Integer] the (unique) ID of the layout category
578
+ attribute :id
579
+
580
+ # @!attribute description
581
+ # @return [String, nil] the description of the layout category
582
+ attribute :description
583
+
584
+ # @!attribute layouts
585
+ # @return [Array<Layout>] the layouts that are associated with
586
+ # the category
587
+ # FIXME: Missing endpoint in LWS
588
+ has_many :layouts, class_name: "LWS::DigitalSignage::Layout",
589
+ uri: "layout/categories/:category_id/layouts(/:id)"
590
+
591
+ # @!attribute name
592
+ # @return [String] the name of the layout category
593
+ attribute :name
594
+
595
+ # @!attribute created_at [r]
596
+ # @return [String] the timestamp of when the layout category was created
597
+ attribute :created_at
598
+
599
+ # @!attribute updated_at [r]
600
+ # @return [String] the timestamp of when the layout category was last updated
601
+ attribute :updated_at
602
+ end
603
+
604
+ # = The layout element class
605
+ #
606
+ # @note
607
+ # This class is only used within the context of the {Layout::Version} class.
608
+ class Layout::Element < LWS::Generic::Model
609
+ use_api LWS::DigitalSignage.api
610
+
611
+ # @!attribute id [r]
612
+ # @return [Integer] the (unique) ID of the layout element
613
+ attribute :id
614
+
615
+ # @!attribute asset_storage_ids
616
+ # @return [Array<String>] the storage IDs of the assets of the layout element
617
+ attribute :asset_storage_ids
618
+
619
+ # @!attribute asset_urls
620
+ # This is a list of mappings of the asset filename (key +"filename"+) to the
621
+ # asset URL (key +"url"+).
622
+ #
623
+ # @return [Array<Hash{String => String}>] the assets of the layout element
624
+ attribute :asset_urls
625
+
626
+ # @!attribute customizables
627
+ # @return [Array<Layout::Element::Customizable>] the customizable properties
628
+ # of the layout element
629
+ has_many :customizables, class_name: "LWS::DigitalSignage::Layout::Element::Customizable"
630
+
631
+ # @!attribute index
632
+ # @return [Integer, nil] the index of the element within the list of
633
+ # layout elements of the associated layout version
634
+ attribute :index
635
+
636
+ # @!attribute klass
637
+ # @return [String] the class of the layout element
638
+ attribute :klass
639
+
640
+ # @!attribute parent
641
+ # @return [Layout, nil] the parent of the layout element
642
+ # FIXME: Missing endpoint in LWS
643
+ belongs_to :parent, class_name: "LWS::DigitalSignage::Layout::Element",
644
+ foreign_key: :parent_id
645
+
646
+ # @!attribute parent_id
647
+ # @return [Integer, nil] the ID of the parent of the layout element
648
+ attribute :parent_id
649
+
650
+ # @!attribute properties
651
+ # @return [Array<Layout::Element::Property>] the properties of the layout
652
+ # element
653
+ has_many :properties, class_name: "LWS::DigitalSignage::Layout::Element::Property"
654
+
655
+ # @!attribute version
656
+ # @return [Layout::Verion] the layout version that contains the element
657
+ # FIXME: Missing endpoint in LWS
658
+ belongs_to :version, class_name: "LWS::DigitalSignage::Layout::Version",
659
+ foreign_key: :layout_version_id
660
+
661
+ # @!attribute created_at [r]
662
+ # @return [String] the timestamp of when the layout element was created
663
+ attribute :created_at
664
+
665
+ # @!attribute updated_at [r]
666
+ # @return [String] the timestamp of when the layout element was last
667
+ # updated
668
+ attribute :updated_at
669
+ end
670
+
671
+ # = The layout element customizable class
672
+ #
673
+ # @note
674
+ # This class is only used within the context of the {Layout::Element} class.
675
+ class Layout::Element::Customizable < LWS::Generic::Model
676
+ use_api LWS::DigitalSignage.api
677
+
678
+ # @!attribute id [r]
679
+ # @return [Integer] the (unique) ID of the layout element customizable
680
+ # property
681
+ attribute :id
682
+
683
+ # @!attribute attr
684
+ # @return [String] the customizable attribute/property name
685
+ attribute :attr
686
+
687
+ # @!attribute element
688
+ # @return [Layout::element] the layout element the customizable property
689
+ # is for
690
+ belongs_to :element, class_name: "LWS::DigitalSignage::Layout::Element"
691
+
692
+ # @!attribute element_id
693
+ # @return [Integer] the ID of the layout element the customizable is for
694
+ attribute :element_id
695
+
696
+ # @!attribute hint_message
697
+ # @return [String] the customizable attribute/property value
698
+ attribute :hint_message
699
+
700
+ # @!attribute presets
701
+ # @return [Array<Hash>] the presets for attribute values (label to value)
702
+ attribute :presets
703
+
704
+ # @!attribute uuid
705
+ # @return [String] the UUID of the customizable attribute/property
706
+ attribute :uuid
707
+
708
+ # @!attribute created_at [r]
709
+ # @return [String] the timestamp of when the layout element customizable
710
+ # was created
711
+ attribute :created_at
712
+
713
+ # @!attribute updated_at [r]
714
+ # @return [String] the timestamp of when the layout element customizable
715
+ # was last updated
716
+ attribute :updated_at
717
+ end
718
+
719
+ # = The layout element property class
720
+ #
721
+ # @note
722
+ # This class is only used within the context of the {Layout::Element} class.
723
+ class Layout::Element::Property < LWS::Generic::Model
724
+ use_api LWS::DigitalSignage.api
725
+
726
+ # @!attribute id [r]
727
+ # @return [Integer] the (unique) ID of the layout element property
728
+ attribute :id
729
+
730
+ # @!attribute attr
731
+ # @return [String] the attribute/property name
732
+ attribute :attr
733
+
734
+ # @!attribute element
735
+ # @return [Layout::Element] the layout element the property
736
+ # is for
737
+ belongs_to :element, class_name: "LWS::DigitalSignage::Layout::Element"
738
+
739
+ # @!attribute element_id
740
+ # @return [Integer] the ID of the layout element the property is for
741
+ attribute :element_id
742
+
743
+ # @!attribute locked
744
+ # @return [Boolean] whether the attribute/property value is locked
745
+ attribute :locked
746
+
747
+ # @!attribute value
748
+ # @return [String] the attribute/property value
749
+ attribute :value
750
+
751
+ # @!attribute created_at [r]
752
+ # @return [String] the timestamp of when the layout element was created
753
+ attribute :created_at
754
+
755
+ # @!attribute updated_at [r]
756
+ # @return [String] the timestamp of when the layout element was last
757
+ # updated
758
+ attribute :updated_at
759
+ end
760
+
761
+ # = The layout version class
762
+ #
763
+ # @note
764
+ # This class is only used within the context of the {Layout} class.
765
+ class Layout::Version < LWS::Generic::Model
766
+ use_api LWS::DigitalSignage.api
767
+ uri "layout/Layout_id/versions(/:id)"
768
+
769
+ # @!attribute id [r]
770
+ # @return [Integer] the (unique) ID of the layout version
771
+ attribute :id
772
+
773
+ # @!attribute elements
774
+ # @return [Array<Layout::Element>] the elements contained in the layout
775
+ # version
776
+ has_many :elements, class_name: "LWS::DigitalSignage::Layout::Element"
777
+
778
+ # @!attribute layout
779
+ # @return [Layout] the layout the layout version is for
780
+ belongs_to :layout
781
+
782
+ # @!attribute layout_id
783
+ # @return [Integer] the ID of the layout the layout version is for
784
+ attribute :layout_id
785
+
786
+ # @!attribute created_at [r]
787
+ # @return [String] the timestamp of when the layout version was created
788
+ attribute :created_at
789
+
790
+ # @!attribute updated_at [r]
791
+ # @return [String] the timestamp of when the layout version was last updated
792
+ attribute :updated_at
793
+ end
794
+
479
795
  # = The player class
480
796
  class Player < LWS::Generic::Model
481
797
  use_api LWS::DigitalSignage.api
@@ -556,7 +872,7 @@ module LWS::DigitalSignage
556
872
  # @!attribute release_channel_id
557
873
  # @return [Integer] the ID of the player OS release channel used by the
558
874
  # player
559
- attribute :releasee_channel_id
875
+ attribute :release_channel_id
560
876
 
561
877
  # @!attribute requests
562
878
  # @return [Array<Player::Feedback>] the requests for the player
@@ -613,7 +929,7 @@ module LWS::DigitalSignage
613
929
  # @!attribute supplier
614
930
  # @return [LWS::Auth::Company] the supplier of the component part
615
931
  belongs_to :supplier, class_name: "LWS::Auth::Company",
616
- foreign_key: "supplier_id",
932
+ foreign_key: :supplier_id,
617
933
  uri: "companies/:id"
618
934
 
619
935
  # @!attribute supplier_id
@@ -1368,7 +1684,7 @@ module LWS::DigitalSignage
1368
1684
  # @!attribute screenshot
1369
1685
  # This field should be set once the action has been processed (see
1370
1686
  # {#processed}) and the action is +"send_screenshot"+.
1371
- #
1687
+ #
1372
1688
  # @return [Player::Screenshot, nil] the player screenshot as a response to
1373
1689
  # the action request +"send_screenshot"+
1374
1690
  belongs_to :screenshot, class_name: "LWS::DigitalSignage::Player::Screenshot",
@@ -1429,6 +1745,128 @@ module LWS::DigitalSignage
1429
1745
  # @!attribute value
1430
1746
  # @return [String, nil] the value of the player tag
1431
1747
  attribute :value
1748
+
1749
+ # @!attribute created_at [r]
1750
+ # @return [String] the timestamp of when the player tag was created
1751
+ attribute :created_at
1752
+
1753
+ # @!attribute updated_at [r]
1754
+ # @return [String] the timestamp of when the player tag was last updated
1755
+ attribute :updated_at
1756
+ end
1757
+
1758
+ # = The slide class
1759
+ class Slide < LWS::Generic::Model
1760
+ use_api LWS::DigitalSignage.api
1761
+
1762
+ # @!attribute id [r]
1763
+ # @return [Integer] the (unique) ID of the slide
1764
+ attribute :id
1765
+
1766
+ # @!attribute account
1767
+ # @return [LWS::Auth::Account] the account used for creating the slide
1768
+ belongs_to :account, class_name: "LWS::Auth::Account"
1769
+
1770
+ # @!attribute account_id
1771
+ # @return [Integer] the ID of the account used for creating the slide
1772
+ attribute :account_id
1773
+
1774
+ # @!attribute company
1775
+ # @return [LWS::Auth::Company] the company the slide belongs to
1776
+ belongs_to :company, class_name: "LWS::Auth::Company"
1777
+
1778
+ # @!attribute company_id
1779
+ # @return [Integer] the ID of the company the slide belongs to
1780
+ attribute :company_id
1781
+
1782
+ # @!attribute layout
1783
+ # @return [LWS::Layout] the layout the slide uses
1784
+ belongs_to :layout
1785
+
1786
+ # @!attribute layout_id
1787
+ # @return [Integer] the ID of the layout the slide uses
1788
+ attribute :layout_id
1789
+
1790
+ # @!attribute name
1791
+ # @return [String] the name of the slide
1792
+ attribute :name
1793
+
1794
+ # @!attribute order_priority
1795
+ # @return [Integer] the order priority within a playlist for a channel
1796
+ attribute :order_priority
1797
+
1798
+ # @!attribute schedules
1799
+ # @return [Array<Schedule>] the slide schedules that apply for the slide
1800
+ # FIXME: Missing endpoint in LWS
1801
+ has_many :schedules, class_name: "LWS::DigitalSignage::Slide::Schedule"
1802
+
1803
+ # @!attribute created_at [r]
1804
+ # @return [string] the timestamp of when the slide was created
1805
+ attribute :created_at
1806
+
1807
+ # @!attribute updated_at [r]
1808
+ # @return [string] the timestamp of when the slide was last updated
1809
+ attribute :updated_at
1810
+ end
1811
+
1812
+ # = The slide schedule class
1813
+ class Slide::Schedule < LWS::Generic::Model
1814
+ use_api LWS::DigitalSignage.api
1815
+
1816
+ # @!attribute id [r]
1817
+ # @return [Integer] the (unique) ID of the slide schedule
1818
+ attribute :id
1819
+
1820
+ # @!attribute date_end
1821
+ # @return [Date] the date after which the slide schedule becomes inactive
1822
+ attribute :date_end
1823
+
1824
+ # @!attribute date_start
1825
+ # @return [Date] the date on which the slide schedule becomes active
1826
+ attribute :date_start
1827
+
1828
+ # @!attribute duration
1829
+ # @return [Integer] the duration of the slide within the slide schedule
1830
+ attribute :duration
1831
+
1832
+ # @!attribute name
1833
+ # @return [String] the name of the slide schedule
1834
+ attribute :name
1835
+
1836
+ # @!attribute priority
1837
+ # @return ["low", "normal", "high"] the priority of the slide schedule
1838
+ # with respect to other slide schedules
1839
+ attribute :priority
1840
+
1841
+ # @!attribute skip_every
1842
+ # @return [Integer] how many times to skip the slide within the slide
1843
+ # schedule
1844
+ attribute :skip_every
1845
+
1846
+ # @!attribute slides
1847
+ # @return [Array<Slide>] the slides that use the slide schedule
1848
+ # FIXME: Missing endpoint in LWS
1849
+ has_many :slides, class: "LWS::DigitalSignage::Slide"
1850
+
1851
+ # @!attribute time_end
1852
+ # @return [Time] the time after which the slide schedule becomes inactive
1853
+ attribute :time_end
1854
+
1855
+ # @!attribute time_start
1856
+ # @return [Time] the time on which the slide schedule becomes active
1857
+ attribute :time_start
1858
+
1859
+ # @!attribute visible
1860
+ # @return [Boolean] whether the slide is visible within the slide schedule
1861
+ attribute :visible
1862
+
1863
+ # @!attribute created_at [r]
1864
+ # @return [string] the timestamp of when the slide schedule was created
1865
+ attribute :created_at
1866
+
1867
+ # @!attribute updated_at [r]
1868
+ # @return [string] the timestamp of when the slide schedule was last updated
1869
+ attribute :updated_at
1432
1870
  end
1433
1871
 
1434
1872
  end
@@ -144,7 +144,7 @@ module LWS::Generic
144
144
  # @return [Hash, Trueclass] a mapping of attributes names to values,
145
145
  # or +true+ if no save action was necessary.
146
146
  def save
147
- return true unless changed?
147
+ return true unless changed? || !persisted?
148
148
  result = super
149
149
  changes_applied if result
150
150
  result
@@ -175,4 +175,72 @@ module LWS::Generic
175
175
  attribute :updated_at
176
176
  end
177
177
 
178
+ # = The storage class
179
+ #
180
+ # This class can be used to upload files for this app module.
181
+ class Storage
182
+ # @!visibility private
183
+ def self.use_api(api)
184
+ @connection = Faraday.new(url: api.url_prefix) do |c|
185
+ config = LWS.config
186
+
187
+ # Request
188
+ c.request :json
189
+
190
+ # Response
191
+ c.use LWS::JSONLogger, config.logger if config.json_debug
192
+ c.use LWS::HTTPLogger, config.logger, config.http_debug_headers if config.http_debug
193
+
194
+ # Adapter
195
+ if config.http_persistent
196
+ c.adapter :net_http_persistent
197
+ else
198
+ c.adapter Faraday.default_adapter
199
+ end
200
+ end
201
+ end
202
+
203
+ # Uploads a file (or IO object) to the storage of the app module.
204
+ #
205
+ # The resulting storage ID can be used in model attributes that refer to storage
206
+ # IDs (e.g. {DigitalSignage::Layout::Element#asset_storage_ids}).
207
+ #
208
+ # @param file_or_io [File, IO] the file (or IO object) to upload
209
+ # @param filename [String] the filename to use for the uploaded file/IO object
210
+ # @param content_type [String] the content type of the uploaded file/IO object
211
+ # @return [String, nil] the storage ID (if successful)
212
+ def self.create(file_or_io, filename, content_type = "application/octet-stream")
213
+ return nil if file_or_io.closed?
214
+
215
+ data = file_or_io.read
216
+ checksum = Digest::MD5.base64digest(data)
217
+ body = { blob: { filename: filename,
218
+ content_type: content_type,
219
+ byte_size: data.length,
220
+ checksum: checksum } }
221
+ res = @connection.post do |req|
222
+ req.url "rails/active_storage/direct_uploads"
223
+ req.headers["Accept"] = "application/json"
224
+ req.headers["Content-Type"] = "application/json"
225
+ req.body = body.to_json
226
+ end
227
+
228
+ if res.success?
229
+ result = JSON.parse(res.body)
230
+ res = @connection.put do |req|
231
+ req.url result.dig("direct_upload", "url")
232
+ result.dig("direct_upload", "headers").each do |hdr, val|
233
+ req.headers[hdr] = val
234
+ end
235
+ req.body = data
236
+ end
237
+ if res.success?
238
+ result["signed_id"]
239
+ end
240
+ else
241
+ nil
242
+ end
243
+ end
244
+ end
245
+
178
246
  end
@@ -33,6 +33,11 @@ module LWS::Resource
33
33
  use_api LWS::Resource.api
34
34
  end
35
35
 
36
+ # (see Generic::Storage)
37
+ class Storage < LWS::Generic::Storage
38
+ use_api LWS::Resource.api
39
+ end
40
+
36
41
  ### App specific classes
37
42
 
38
43
  # = The collection class
@@ -168,7 +173,7 @@ module LWS::Resource
168
173
  # = The collection post class
169
174
  class Collection::Post < Collection::Item
170
175
  use_api LWS::Resource.api
171
-
176
+
172
177
  # @!attribute author
173
178
  # @return [String] the author of the post
174
179
  attribute :author
@@ -176,11 +181,11 @@ module LWS::Resource
176
181
  # @!attribute avatar
177
182
  # @return [Hash] the URL information of the avatar image of the post
178
183
  attribute :avatar
179
-
184
+
180
185
  # @!attribute category
181
186
  # @return [String] the category of the post
182
187
  attribute :category
183
-
188
+
184
189
  # @!attribute comments
185
190
  # @return [String] the comments of the post
186
191
  attribute :comments
@@ -188,7 +193,7 @@ module LWS::Resource
188
193
  # @!attribute description
189
194
  # @return [String] the description of the post
190
195
  attribute :description
191
-
196
+
192
197
  # @!attribute description
193
198
  # @return [String] the description of the post
194
199
  attribute :enclosures
@@ -199,29 +204,29 @@ module LWS::Resource
199
204
 
200
205
  # @!attribute handle
201
206
  # @return [String] the handle of the post
202
- attribute :handle
207
+ attribute :handle
203
208
 
204
209
  # @!attribute link
205
210
  # @return [String] the link of the post
206
211
  attribute :link
207
-
212
+
208
213
  # @!attribute link
209
214
  # @return [String] the timestamp of the modification date of the post
210
215
  attribute :modification_date
211
-
216
+
212
217
  # @!attribute order_priority
213
218
  # @return [Integer] the order priority of the of the post (ascending;
214
219
  # 0 is lowers)
215
220
  attribute :order_priority
216
-
221
+
217
222
  # @!attribute link
218
223
  # @return [String] the timestamp of the publication date of the post
219
224
  attribute :publication_date
220
-
225
+
221
226
  # @!attribute source_url
222
227
  # @return [String] the source URL of the post
223
228
  attribute :source_url
224
-
229
+
225
230
  # @!attribute summary
226
231
  # @return [String] the summary of the post
227
232
  attribute :summary
@@ -376,7 +381,7 @@ module LWS::Resource
376
381
 
377
382
  # @!attribute observation
378
383
  # @return [Boolean] whether the weather location forecast is a
379
- # current observation
384
+ # current observation
380
385
  attribute :observation
381
386
 
382
387
  # @!attribute temperature
@@ -50,7 +50,7 @@ module LWS
50
50
  end
51
51
 
52
52
  end
53
-
53
+
54
54
  end
55
55
 
56
56
  end
@@ -18,7 +18,7 @@ module LWS
18
18
  class JSONParser < Faraday::Response::Middleware
19
19
 
20
20
  def parse(body)
21
- data = MultiJson.load(body, symbolize_keys: true)
21
+ data = MultiJson.load(body, symbolize_keys: true) || {}
22
22
  metadata = data.delete(:metadata)
23
23
  errors = data.delete(:errors)
24
24
 
@@ -10,7 +10,7 @@
10
10
 
11
11
 
12
12
  module LWS
13
-
13
+
14
14
  module Middleware
15
15
 
16
16
  # @private
data/lib/lws/version.rb CHANGED
@@ -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 = '6.2.3'.freeze
16
+ VERSION = '6.3.0'.freeze
17
17
 
18
18
  end
@@ -240,6 +240,163 @@ class TestDigitalSignageDisplayResolution < MiniTest::Test
240
240
 
241
241
  end
242
242
 
243
+ class TestDigitalSignageLayout < MiniTest::Test
244
+
245
+ include LWS::DigitalSignage
246
+
247
+ def setup
248
+ @layout = Layout.find(1)
249
+ end
250
+
251
+ def test_valid
252
+ refute_nil(@layout)
253
+ assert_instance_of(Layout, @layout)
254
+ refute_nil(@layout.id)
255
+ end
256
+
257
+ def test_valid_associations
258
+ # FIXME: Missing endpoint in LWS
259
+ #assert_instance_of(Layout::Category, @layout.categories.first)
260
+ # FIXME: Missing parent_id field in LWS
261
+ #assert_instance_of(Layout, @layout.parent)
262
+ # FIXME: Missing endpoint in LWS
263
+ #assert_instance_of(Slide, @layout.slides.first)
264
+ assert_instance_of(Layout::Version, @layout.versions.find(1))
265
+ end
266
+
267
+ end
268
+
269
+ class TestDigitalSignageLayoutCategory < MiniTest::Test
270
+
271
+ include LWS::DigitalSignage
272
+
273
+ def setup
274
+ @layout_category = Layout::Category.find(1)
275
+ end
276
+
277
+ def test_valid
278
+ refute_nil(@layout_category)
279
+ assert_instance_of(Layout::Category, @layout_category)
280
+ refute_nil(@layout_category.id)
281
+ end
282
+
283
+ def test_valid_associations
284
+ # FIXME: Missing endpoint in LWS
285
+ #assert_instance_of(Layout, @layout_categories.layouts.first)
286
+ end
287
+
288
+ end
289
+
290
+ class TestDigitalSignageLayoutElement < MiniTest::Test
291
+
292
+ include LWS::DigitalSignage
293
+
294
+ def setup
295
+ @layout = Layout.find(1)
296
+ # Layout versions only exist as child objects of layouts
297
+ @layout_version = @layout.versions.find(1)
298
+ # Layout elements only exist as child objects of layout versions
299
+ @layout_element = @layout_version.elements.first
300
+ end
301
+
302
+ def test_valid
303
+ refute_nil(@layout_element)
304
+ assert_instance_of(Layout::Element, @layout_element)
305
+ refute_nil(@layout_element.id)
306
+ end
307
+
308
+ def test_valid_associations
309
+ assert_instance_of(Layout::Element::Customizable, @layout_element.customizables.first)
310
+ assert_instance_of(Layout::Element::Property, @layout_element.properties.first)
311
+ # FIXME: Missing endpoint in LWS
312
+ #assert_instance_of(Layout::Version, @layout_element.version)
313
+ #assert_equal(@layout_version, @layout_element.version)
314
+ # FIXME: Missing endpoint in LWS
315
+ #assert_instance_of(Layout::Element, @layout_element.parent)
316
+ end
317
+
318
+ end
319
+
320
+ class TestDigitalSignageLayoutElementCustomizable < MiniTest::Test
321
+
322
+ include LWS::DigitalSignage
323
+
324
+ def setup
325
+ @layout = Layout.find(1)
326
+ # Layout versions only exist as child objects of layouts
327
+ @layout_version = @layout.versions.find(1)
328
+ # Layout elements only exist as child objects of layout versions
329
+ @layout_element = @layout_version.elements.first
330
+ # Layout element customizables only exist as child objects of layout elements
331
+ @layout_element_customizable = @layout_element.customizables.first
332
+ end
333
+
334
+ def test_valid
335
+ refute_nil(@layout_element_customizable)
336
+ assert_instance_of(Layout::Element::Customizable, @layout_element_customizable)
337
+ refute_nil(@layout_element_customizable.id)
338
+ end
339
+
340
+ def test_valid_associations
341
+ # FIXME: Missing endpoint in LWS
342
+ #assert_instance_of(Layout::Element, @layout_element_customizable.element)
343
+ #assert_equal(@layout_element, @layout_element_customizable.element)
344
+ end
345
+
346
+ end
347
+
348
+ class TestDigitalSignageLayoutElementProperty < MiniTest::Test
349
+
350
+ include LWS::DigitalSignage
351
+
352
+ def setup
353
+ @layout = Layout.find(1)
354
+ # Layout versions only exist as child objects of layouts
355
+ @layout_version = @layout.versions.find(1)
356
+ # Layout elements only exist as child objects of layout versions
357
+ @layout_element = @layout_version.elements.first
358
+ # Layout element properties only exist as child objects of layout elements
359
+ @layout_element_property = @layout_element.properties.first
360
+ end
361
+
362
+ def test_valid
363
+ refute_nil(@layout_element_property)
364
+ assert_instance_of(Layout::Element::Property, @layout_element_property)
365
+ refute_nil(@layout_element_property.id)
366
+ end
367
+
368
+ def test_valid_associations
369
+ # FIXME: Missing endpoint in LWS
370
+ #assert_instance_of(Layout::Element, @layout_element_property.element)
371
+ #assert_equal(@layout_element, @layout_element_property.element)
372
+ end
373
+
374
+ end
375
+
376
+ class TestDigitalSignageLayoutVersion < MiniTest::Test
377
+
378
+ include LWS::DigitalSignage
379
+
380
+ def setup
381
+ @layout = Layout.find(1)
382
+ # Layout versions only exist as child objects of layouts
383
+ @layout_version = @layout.versions.find(1)
384
+ end
385
+
386
+ def test_valid
387
+ refute_nil(@layout_version)
388
+ assert_instance_of(Layout::Version, @layout_version)
389
+ refute_nil(@layout_version.id)
390
+ end
391
+
392
+ def test_valid_associations
393
+ assert_instance_of(Layout::Element, @layout_version.elements.first)
394
+ assert_instance_of(Layout, @layout_version.layout)
395
+ assert_equal(@layout, @layout_version.layout)
396
+ end
397
+
398
+ end
399
+
243
400
  class TestDigitalSignagePlayer < MiniTest::Test
244
401
 
245
402
  include LWS::DigitalSignage
@@ -828,3 +985,50 @@ class TestDigitalSignagePlayerTag < MiniTest::Test
828
985
  end
829
986
 
830
987
  end
988
+
989
+ class TestDigitalSignageSlide < MiniTest::Test
990
+
991
+ include LWS::DigitalSignage
992
+
993
+ def setup
994
+ @slide = Slide.find(1)
995
+ end
996
+
997
+ def test_valid
998
+ refute_nil(@slide)
999
+ assert_instance_of(Slide, @slide)
1000
+ refute_nil(@slide.id)
1001
+ end
1002
+
1003
+ def test_valid_associations
1004
+ assert_instance_of(LWS::Auth::Account, @slide.account)
1005
+ assert_instance_of(LWS::Auth::Company, @slide.company)
1006
+ assert_instance_of(Layout, @slide.layout)
1007
+ end
1008
+
1009
+ end
1010
+
1011
+ class TestDigitalSignageSlideSchedule < MiniTest::Test
1012
+
1013
+ include LWS::DigitalSignage
1014
+
1015
+ def setup
1016
+ @slide = Slide.find(1)
1017
+ # Slide schedules only exist as decendant objects of players
1018
+ # FIXME: Endpoint is missing in LWS
1019
+ @slide_schedule = @slide.schedules.first
1020
+ end
1021
+
1022
+ # FIXME: Endpoint is missing in LWS
1023
+ #def test_valid
1024
+ # refute_nil(@slide_schedule)
1025
+ # assert_instance_of(Slide::Schedule, @slide_schedule)
1026
+ # refute_nil(@slide_schedule.id)
1027
+ #end
1028
+
1029
+ # FIXME: Endpoint is missing in LWS
1030
+ #def test_valid_associations
1031
+ # assert_instance_of(Slide, @slide_schedules.slides.first)
1032
+ #end
1033
+
1034
+ end
data/test/generic_test.rb CHANGED
@@ -53,6 +53,12 @@ class TestGenericModel < MiniTest::Test
53
53
  end
54
54
 
55
55
  def test_dirty
56
+ # Always save a non-persisted object (even without changes)
57
+ configuration = Configuration.new
58
+ assert_empty(configuration.changes)
59
+ configuration.save
60
+ refute_empty(configuration.errors.messages)
61
+
56
62
  # No changes for a just found instance
57
63
  configuration = Configuration.find(@configuration.id)
58
64
  refute(configuration.changed?)
@@ -100,3 +106,14 @@ class TestGenericConfiguration < MiniTest::Test
100
106
  end
101
107
 
102
108
  end
109
+
110
+ class TestGenericStorage < MiniTest::Test
111
+
112
+ # Generic class needs to be accessed under some kind of app
113
+ include LWS::Resource
114
+
115
+ def test_upload
116
+ data = StringIO.new("some file contents\n")
117
+ refute_nil(Storage.create(data, "test.txt", "text/plain"))
118
+ end
119
+ end
@@ -20,7 +20,7 @@ require "test_helper"
20
20
  # * Collection::WeatherLocation
21
21
  # * Collection::WeatherLocation::Forecast
22
22
 
23
- class TestCollection < MiniTest::Test
23
+ class TestResourceCollection < MiniTest::Test
24
24
 
25
25
  include LWS::Resource
26
26
 
@@ -43,7 +43,7 @@ class TestCollection < MiniTest::Test
43
43
 
44
44
  end
45
45
 
46
- class TestCollectionItem < MiniTest::Test
46
+ class TestResourceCollectionItem < MiniTest::Test
47
47
 
48
48
  include LWS::Resource
49
49
 
@@ -65,7 +65,7 @@ class TestCollectionItem < MiniTest::Test
65
65
 
66
66
  end
67
67
 
68
- class TestFolder < MiniTest::Test
68
+ class TestResourceFolder < MiniTest::Test
69
69
 
70
70
  include LWS::Resource
71
71
 
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: 6.2.3
4
+ version: 6.3.0
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: 2019-03-25 00:00:00.000000000 Z
11
+ date: 2019-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday_middleware