intranet-pictures 1.1.0 → 2.0.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: 375bdf2fb9b0a0354f3066e44c59a4426077916642a248a9180aabc3842628d5
4
- data.tar.gz: 34b5b68ae804b7a441320eee02880726ce8ca85eb15a813f9e49ab99c64491a6
3
+ metadata.gz: f83afa6acab98f33abb964031b20ee5e3e13a9225ff3ec4525be209c87c66f51
4
+ data.tar.gz: 1c43a4f8cc550fe3900684a81e93ed0e50276ed59154f166132b1395d0748911
5
5
  SHA512:
6
- metadata.gz: 7ba048e77bb9b56447962e17c005c28e14f3ef30795cc218610e485be2ab7ef2da3df9faa0a189704391bae6d55bb75245ba925899093b4d56a58dfdf394cfad
7
- data.tar.gz: 99eac1be0abd8986a67e3fe0ea09700a74304a053d3b33cff10c7fe7c30850942232655e48c42d2064de366829a01a835f8fc101e1052d1ec0cd961c82425464
6
+ metadata.gz: 9746b40dee3c630e69510789eed1d3f937f88441b7a484c0a139d90b7eacfdff63394875bc8122e9efea0583c6955fbc3da77852bb4816a1615952b3658de099
7
+ data.tar.gz: 9e8d8f8903b495bb1dbbacf010cea817f11440a0475b2eb6b98dc7b6e0576ea1dd6d1583cff63f27a9f607f384d108e1a6fa8dc969d009ba43d57b3e544cccb9
@@ -5,7 +5,7 @@ require 'mimemagic'
5
5
 
6
6
  module Intranet
7
7
  module Pictures
8
- # Provides pictures data and pictures groups listings from a database file in JSON format.
8
+ # Provides pictures data and pictures listings from a database file in JSON format.
9
9
  #
10
10
  # === Structure of the JSON database
11
11
  # See the example below.
@@ -14,37 +14,34 @@ module Intranet
14
14
  #
15
15
  # Pictures are described individually as a hash in the +pictures+ array. The mandatory keys in
16
16
  # this hash are:
17
- # * +id+ : unique identifier of the picture
18
17
  # * +uri+ : location of the picture, relative to the JSON file
19
18
  # * +title+ : description of the picture
20
19
  # * +datetime+ : date and time of the picture, as a string in ISO8601 format
21
20
  # * +height+ and +width+ : size in pixels of the picture
22
21
  #
23
- # Pictures are meant to be grouped in various group types (event, city, region/country, ...).
24
- # Each group type is defined as an entry in the +groups+ hash and consists of a set of groups,
25
- # each of them described by a hash with the following keys:
22
+ # Additional keys may be added (for instance: event, city, region/country, ...); they will be
23
+ # used to group pictures sharing the same value of a given key.
24
+ # Some groups may be defined in the +groups+ hash to add a thumbnail picture and a brief text
25
+ # description for them. The possible keys in this hash are:
26
26
  # * +id+ : unique identifier of the group, mandatory
27
- # * +title+ : human-readable group name, mandatory
28
27
  # * +brief+ : optional short text associated to the group name
29
28
  # * +uri+ : optional group thumbnail, relative to the JSON file
30
29
  #
31
- # Each image is associated to at most one group in each group type by by a a "foreign key"
32
- # constraint of the type *picture*.+group_type+ = *group*.+id+.
33
30
  # @example Structure of the JSON database (not all mandatory are present for readability)
34
31
  # {
35
32
  # "title": "gallery title",
36
33
  # "groups": {
37
34
  # "event": [
38
- # { "id": "party", "title": "...", "brief": "...", "uri": "party.jpg", ... },
35
+ # { "id": "Party", "brief": "...", "uri": "party.jpg", ... },
39
36
  # { ... }
40
37
  # ],
41
38
  # "city": [
42
- # { "id": "houston", "title": "...", "uri": "houston.png", ... },
39
+ # { "id": "Houston", "uri": "houston.png", ... },
43
40
  # { ... }
44
41
  # ]
45
42
  # },
46
43
  # "pictures": [
47
- # { "uri": "dir/pic0.jpg", "datetime": "...", "event": "party", "city": "houston", ... },
44
+ # { "uri": "dir/pic0.jpg", "datetime": "...", "event": "Party", "city": "Houston", ... },
48
45
  # { ... }
49
46
  # ]
50
47
  # }
@@ -66,47 +63,16 @@ module Intranet
66
63
  @json.fetch('title').to_s
67
64
  end
68
65
 
69
- # Returns the list of available group types.
70
- # @return [Array<String>] The available group types.
71
- # @raise KeyError If no group type is defined in JSON file.
72
- def group_types
73
- load_json
74
- @json.fetch('groups').keys
75
- end
76
-
77
- # Returns the list of the groups satisfying the following conditions:
78
- # * the group is of the given +type+, and
79
- # * at least one picture belonging to that group matches the +selector+.
80
- # Results are returned ordered by *group*.+sort_by+ in ascending order if +asc+, and in
81
- # descending order otherwise.
82
- # @param type [String] The group type.
83
- # @param selector [Hash<String,String>] The pictures selector, interpreted as a logical AND
84
- # combination of all key/value pairs provided.
85
- # @param sort_by [String] The group field to sort the results by, or nil if results should be
86
- # returned without particular sorting.
87
- # @param asc [Boolean] True to sort returned groups in ascending order, False to sort in
88
- # descending order.
89
- # @return [Array<Hash{'id'=>String, 'title'=>String, ...}>] The selected groups.
90
- # @raise KeyError If JSON file is malformed, if +type+ does not match an existing group type,
91
- # or if +sort_by+ is not an existing group field.
92
- def list_groups(type, selector = {}, sort_by = nil, asc = true)
93
- load_json
94
- groups = select_groups(type, selector).map { |g| g.except('uri') }
95
- groups.sort_by! { |g| g.fetch(sort_by) } unless sort_by.nil?
96
- groups.reverse! unless asc
97
- groups
98
- end
99
-
100
66
  # Returns the list of the pictures matching +selector+.
101
- # Results are returned ordered by *picture*.+sort_by+ in ascending order if +asc+, and in
102
- # descending order otherwise.
67
+ # Results are returned ordered by +sort_by+ in ascending order if +asc+, and in descending
68
+ # order otherwise.
103
69
  # @param selector [Hash<String,String>] The pictures selector, interpreted as a logical AND
104
70
  # combination of all key/value pairs provided.
105
71
  # @param sort_by [String] The picture field to sort the results by, or nil if results should
106
72
  # be returned without particular sorting.
107
- # @param asc [Boolean] True to sort returned pictures in ascending order, False to sort in
108
- # descending order.
109
- # @return [Array<Hash{'id'=>String, 'title'=>String, 'datetime'=>String, 'height'=>Integer,
73
+ # @param asc [Boolean] True to sort returned pictures in ascending order, False to sort them
74
+ # in descending order.
75
+ # @return [Array<Hash{'title'=>String, 'datetime'=>String, 'height'=>Integer,
110
76
  # 'width'=>Integer, ...}>] The selected pictures.
111
77
  # @raise KeyError If JSON file is malformed, or if +sort_by+ is not an existing picture field.
112
78
  def list_pictures(selector = {}, sort_by = nil, asc = true)
@@ -122,35 +88,46 @@ module Intranet
122
88
  # picture.
123
89
  # @return [String, Blob] The MIME type of the picture, and the picture file content.
124
90
  # @raise KeyError If JSON file is malformed, if selector does not match exactly one picture,
125
- # or if the *picture*.+uri+ does not refer to an existing image file.
91
+ # or if the picture +uri+ does not refer to an existing image file.
126
92
  def picture(selector = {})
127
93
  load_json
128
94
  pic = select_pictures(selector)
129
95
  raise KeyError unless pic.size == 1
130
96
 
131
97
  path = File.join(@json_dir, pic.first.fetch('uri'))
132
- open_image_file(path)
98
+ read_image_file(path)
133
99
  end
134
100
 
135
- # Returns the thumbnail picture of the group satisfying the following conditions:
136
- # * the group is of the given +type+, and
137
- # * at least one picture belonging to that group matches the +selector+.
138
- # @param type [String] The group type.
139
- # @param selector [Hash<String,String>] The pictures selector, interpreted as a logical AND
140
- # combination of all key/value pairs provided. The
141
- # selector should return exactly one group.
101
+ # Returns the thumbnail picture of the group whose type is +key+ and named +value+.
102
+ # @param key [String] The group type.
103
+ # @param value [String] The group name.
142
104
  # @return [String, Blob] The MIME type of the picture, and the picture file content. Nil may
143
105
  # be returned if no thumbnail is available for that group.
144
- # @raise KeyError If JSON file is malformed, if selector does not match exactly one group,
145
- # or if the *group*.+uri+ does not refer to an existing image file.
146
- def group_thumbnail(type, selector = {})
106
+ # @raise KeyError If JSON file is malformed, if key/value do not designate exactly one group,
107
+ # or if the group +uri+ does not refer to an existing image file.
108
+ def group_thumbnail(key, value)
147
109
  load_json
148
- group = select_groups(type, selector)
110
+ group = select_group(key, value)
149
111
  raise KeyError unless group.size == 1
150
112
  return nil if group.first['uri'].nil?
151
113
 
152
114
  path = File.join(@json_dir, group.first.fetch('uri'))
153
- open_image_file(path)
115
+ read_image_file(path)
116
+ end
117
+
118
+ # Returns the brief text of the group whose type is +key+ and named +value+.
119
+ # @param key [String] The group type.
120
+ # @param value [String] The group name.
121
+ # @return [String] The brief text of the group, or an empty string if no brief is available.
122
+ # @raise KeyError If JSON file is malformed or if key/value do not designate exactly one
123
+ # group.
124
+ def group_brief(key, value)
125
+ load_json
126
+ group = select_group(key, value)
127
+ raise KeyError unless group.size == 1
128
+ return '' if group.first['brief'].nil?
129
+
130
+ group.first.fetch('brief')
154
131
  end
155
132
 
156
133
  private
@@ -164,7 +141,7 @@ module Intranet
164
141
  @json_time = mtime
165
142
  end
166
143
 
167
- def open_image_file(path)
144
+ def read_image_file(path)
168
145
  mime_type = MimeMagic.by_path(path).type
169
146
  raise KeyError unless mime_type.start_with?('image/')
170
147
 
@@ -179,19 +156,12 @@ module Intranet
179
156
  false
180
157
  end
181
158
 
182
- def select_groups(type, selector)
183
- return @json.fetch('groups').fetch(type) if selector.empty? # optimization
184
-
185
- groups_id = select_pictures_having(type, selector).map { |p| p.fetch(type) }.uniq.compact
186
- @json.fetch('groups').fetch(type).select { |g| groups_id.include?(g.fetch('id')) }
187
- end
188
-
189
159
  def select_pictures(selector)
190
160
  @json.fetch('pictures').select { |p| picture_match?(p, selector) }
191
161
  end
192
162
 
193
- def select_pictures_having(group_type, selector)
194
- @json.fetch('pictures').select { |p| p.key?(group_type) && picture_match?(p, selector) }
163
+ def select_group(type, id)
164
+ @json.fetch('groups').fetch(type).select { |g| g.fetch('id') == id }
195
165
  end
196
166
  end
197
167
  end
@@ -9,7 +9,7 @@ require_relative 'version'
9
9
  module Intranet
10
10
  module Pictures
11
11
  # The responder for the Pictures monitor module of the Intranet.
12
- class Responder < AbstractResponder
12
+ class Responder < AbstractResponder # rubocop:disable Metrics/ClassLength
13
13
  include Core::HamlWrapper # 'inherits' from methods of HamlWrapper
14
14
 
15
15
  # Returns the name of the module.
@@ -18,30 +18,37 @@ module Intranet
18
18
  NAME
19
19
  end
20
20
 
21
- # The version of the module, according to semantic versionning.
21
+ # Returns the version of the module, according to semantic versionning.
22
22
  # @return [String] The version of the module.
23
23
  def self.module_version
24
24
  VERSION
25
25
  end
26
26
 
27
- # The homepage of the module.
27
+ # Returns the homepage URL of the module.
28
28
  # @return [String] The homepage URL of the module.
29
29
  def self.module_homepage
30
30
  HOMEPAGE_URL
31
31
  end
32
32
 
33
33
  # Initializes a new Pictures responder instance.
34
- # @param provider [#title,#group_types,#list_groups,#group_thumbnail,#list_pictures,#picture]
34
+ # @param provider [#title,#list_pictures,#group_thumbnail,#group_brief,#picture]
35
35
  # The pictures provider.
36
36
  # @see Intranet::Pictures::JsonDbProvider The specification of the provider, and in particular
37
37
  # the minimal mandatory elements that must be returned by the operations.
38
- # @param recents [Array<Hash{group_type:String, sort_by:String, asc:Boolean, limit:Integer}>]
39
- # The description of the recent pictures album to be displayed on the module home page (all
40
- # keys except +group_type+ may be omitted).
41
- # @param home_groups [Array<Hash{group_type:String, sort_by:String, asc:Boolean,
42
- # browse:String, browse_sort_by:String, browse_asc:Boolean}>]
43
- # The description of the groups to be displayed on the module home page. All groups of the
44
- # +group_type+ will be displayed and link to a page showing all groups of the +browse+ type.
38
+ # @param recents [Array<Hash{group_by:String, sort_by:String, sort_order:String,
39
+ # limit:Integer}>]
40
+ # The description of the recent pictures to be displayed on the module home page. Pictures
41
+ # will first be sorted according to +sort_by+ and +sort_order+, then grouped by +group_by+,
42
+ # keeping only the first +limit+ elements, or all if +limit+ is zero. All keys except
43
+ # +group_by+ may be omitted.
44
+ # @param home_groups [Array<Hash{group_by:String, sort_by:String, sort_order:String,
45
+ # browse_group_by:String, browse_sort_by:String, browse_sort_order:String}>]
46
+ # The description of the pictures groups to be displayed on the module home page, after the
47
+ # +recents+. Pictures will first be sorted according to +sort_by+ and +sort_order+, then
48
+ # grouped by +group_by+. The obtained groups will be displayed with their thumbnail,
49
+ # (optional) brief text and a link to display images of that group sorted according to
50
+ # +browse_sort_by+ and +browse_sort_order+ and grouped by +browse_group_by+. All keys except
51
+ # +group_by+ and +browse_group_by+ may be omitted.
45
52
  # @param in_menu [Boolean] Whether the module instance should be displayed in the main
46
53
  # navigation menu or not.
47
54
  def initialize(provider, recents = [], home_groups = [], in_menu = true)
@@ -65,34 +72,42 @@ module Intranet
65
72
  end
66
73
 
67
74
  # Generates the HTML content associated to the given +path+ and +query+.
68
- # === REST API Description:
69
- # * Read-only access to pictures listings under */api/pictures* using +GET+ method, response
70
- # is in JSON format with the following structure:
75
+ # @param path [String] The requested URI, relative to that module root URI.
76
+ # @param query [Hash<String,String>] The URI variable/value pairs, if any.
77
+ # @return [Integer, String, String] The HTTP return code, the MIME type and the answer body.
78
+ #
79
+ # Relevant queries are as follows:
80
+ #
81
+ # * If +path+ is +/browse.html+, key/value pairs may be used to restrict the displayed images
82
+ # to those satisfying all the pairs. Moreover, +sort_by+ (followed by a key), +sort_order+
83
+ # (followed by either +asc+ or +desc+) and +group_by+ may be used to alter the way images
84
+ # are displayed.
85
+ # * If +path+ is +/api/group_thumbnail+ or +/api/group_brief+, query must contain only a
86
+ # single key/value pair designating the pictures group.
87
+ # * If +path+ is +/api/pictures+, key/value pairs may be used to restrict the displayed images
88
+ # to those satisfying all the pairs. Moreover, +sort_by+ (followed by a key), and
89
+ # +sort_order+ (followed by either +asc+ or +desc+) may be used to alter the order in which
90
+ # images are returned.
91
+ # * If +path+ is +api/picture+, key/value pairs must be used to select a single image from the
92
+ # gallery.
93
+ #
94
+ # When +path+ is +/api/pictures+, the selected pictures are returned in JSON format (REST API)
95
+ # with the following structure:
71
96
  # [
72
97
  # { "id": "...", "height": 480, "width": 640, "title": "...", "datetime": "...", ... },
73
98
  # { ... }
74
99
  # ]
75
- # * Read-only access to groups listings under */api/groups/*+group_type+ using +GET+ method,
76
- # response is in JSON format with the following structure:
77
- # [
78
- # { "id": "...", "title": "...", ... },
79
- # { ... }
80
- # ]
81
- # @param path [String] The requested URI, relative to that module root URI.
82
- # @param query [Hash<String,String>] The URI variable/value pairs, if any.
83
- # @return [Integer, String, String] The HTTP return code, the MIME type and the answer body.
84
100
  def generate_page(path, query)
85
101
  case path
86
- when %r{^/index\.html$} then serve_home
87
- when %r{^/browse_\w+\.html$}
88
- serve_groups(path.gsub(%r{^/browse_(\w+)\.html$}, '\\1'), query)
102
+ when %r{^/index\.html$} then serve_home
103
+ when %r{^/browse\.html$} then serve_browse(query)
89
104
  when %r{^/api/} then serve_api(path.gsub(%r{^/api}, ''), query)
90
105
  when %r{^/i18n\.js$} then serve_i18n_js
91
106
  else super(path, query)
92
107
  end
93
108
  end
94
109
 
95
- # The title of the Pictures module, as displayed on the web page.
110
+ # Returns the title of the Pictures module, as displayed on the web page.
96
111
  # @return [String] The title of the Pictures module web page.
97
112
  def title
98
113
  @provider.title
@@ -101,23 +116,30 @@ module Intranet
101
116
  private
102
117
 
103
118
  # Extract a selector from the given +query+.
104
- # @return [Hash<String,String>] The picture or group selector.
119
+ # @return [Hash<String,String>] The picture selector.
105
120
  def selector(query)
106
- query.except('sort_by', 'sort_order')
121
+ query.except('group_by', 'sort_by', 'sort_order')
107
122
  end
108
123
 
109
- # Extract the sort criteria from the given +query+.
110
- # @return [String] The key to use to sort pictures or groups, or nil if no sort order is
111
- # specified in +query+.
124
+ # Extract the grouping criteria from the given +query+, ie. the key that will be used to group
125
+ # the selected pictures.
126
+ # @return [String] The key to use to group pictures.
127
+ # @raise KeyError If no grouping criteria is specified.
128
+ def group_by(query)
129
+ query.fetch('group_by')
130
+ end
131
+
132
+ # Extract the sorting criteria from the given +query+, ie. the key that will be used to sort
133
+ # the selected pictures.
134
+ # @return [String] The key to use to sort pictures, or nil if no sorting is specified.
112
135
  def sort_by(query)
113
136
  query.fetch('sort_by')
114
137
  rescue KeyError
115
138
  nil
116
139
  end
117
140
 
118
- # Extract the sort order from the given +query+.
119
- # @return [Boolean] False if the pictures or groups should be sorted in descending order,
120
- # True otherwise.
141
+ # Extract the sorting order from the given +query+.
142
+ # @return [Boolean] True if the pictures should be sorted in ascending order, False otherwise.
121
143
  # @raise KeyError If the query requests an invalid sort order.
122
144
  def sort_order(query)
123
145
  return false if query['sort_order'] == 'desc'
@@ -143,52 +165,55 @@ module Intranet
143
165
  ### Servicing of the HTML "display-able" content ###
144
166
  ##########################################################################
145
167
 
146
- def active_filters(query)
147
- selector(query).map do |k, v|
148
- { k => @provider.list_groups(k, { k => v }).first.fetch('title') }
149
- rescue KeyError
150
- { k => v }
151
- end.reduce({}, :merge)
168
+ def collect_groups(selector, group_by, sort_by, sort_order)
169
+ # Select all pictures, sort them & eventually keep only group names (first occurrence only)
170
+ @provider.list_pictures(selector, sort_by, sort_order).map do |picture|
171
+ picture.fetch(group_by)
172
+ end.uniq
173
+ end
174
+
175
+ def hash_to_query(hash)
176
+ hash.map { |k, v| [k, v].join('=') }.join('&')
152
177
  end
153
178
 
154
179
  def recent_groups
155
180
  @recents.map do |recent|
156
- groups = @provider.list_groups(recent[:group_type], {}, recent[:sort_by], recent[:asc])
181
+ groups = collect_groups({}, group_by(recent), sort_by(recent), sort_order(recent))
157
182
  see_more_url = ''
158
- if recent[:limit].to_i.positive?
159
- groups = groups.first(recent[:limit])
160
- see_more_url = "browse_#{recent[:group_type]}.html?sort_by=#{recent[:sort_by]}"
161
- see_more_url += '&sort_order=desc' unless recent[:asc]
183
+ if recent['limit'].to_i.positive?
184
+ groups = groups.first(recent['limit'].to_i)
185
+ see_more_url = "browse.html?#{hash_to_query(recent.except('limit'))}"
162
186
  end
163
- { group_type: recent[:group_type], groups: groups, see_more_url: see_more_url }
187
+ { group_key: group_by(recent), groups: groups, see_more_url: see_more_url }
164
188
  end
165
189
  end
166
190
 
167
191
  def all_groups
168
- @home_groups.map do |section|
169
- groups = @provider.list_groups(section[:group_type], {}, section[:sort_by], section[:asc])
170
- url_prefix = "browse_#{section[:browse]}.html?sort_by=#{section[:browse_sort_by]}"
171
- url_prefix += '&sort_order=desc' unless section[:browse_asc]
172
- { group_type: section[:group_type], groups: groups, url_prefix: url_prefix }
192
+ @home_groups.map do |sec|
193
+ groups = collect_groups({}, group_by(sec), sort_by(sec), sort_order(sec))
194
+ url_prefix = "browse.html?group_by=#{sec['browse_group_by']}"
195
+ url_prefix += "&sort_by=#{sec['browse_sort_by']}" if sec['browse_sort_by']
196
+ url_prefix += "&sort_order=#{sec['browse_sort_order']}" if sec['browse_sort_order']
197
+ { group_key: group_by(sec), groups: groups, url_prefix: url_prefix }
173
198
  end
174
199
  end
175
200
 
176
- def make_nav(group_type = nil, query = {})
201
+ def make_nav(query = {})
177
202
  h = { I18n.t('nav.home') => '/index.html', I18n.t('pictures.menu') => nil, title => nil }
178
- unless group_type.nil?
203
+ unless query['group_by'].nil?
179
204
  h[title] = 'index.html'
180
- extra_key = I18n.t("pictures.nav.#{group_type}")
181
- filters = active_filters(query).values
205
+ extra_key = I18n.t("pictures.nav.#{group_by(query)}")
206
+ filters = selector(query).values
182
207
  extra_key += " (#{filters.join(', ')})" unless filters.empty?
183
208
  h.store(extra_key, nil)
184
209
  end
185
210
  h
186
211
  end
187
212
 
188
- def gallery_url(group_type, group_id, filters = {})
189
- filters.store(group_type, group_id)
213
+ def gallery_url(key, value, filters = {})
214
+ filters.store(key, value)
190
215
  filters.store('sort_by', 'datetime')
191
- filters.map { |k, v| [k, v].join('=') }.join('&')
216
+ hash_to_query(filters)
192
217
  end
193
218
 
194
219
  def serve_home
@@ -199,9 +224,9 @@ module Intranet
199
224
  [404, '', '']
200
225
  end
201
226
 
202
- def serve_groups(type, query)
203
- groups = @provider.list_groups(type, selector(query), sort_by(query), sort_order(query))
204
- content = to_markup('pictures_browse', nav: make_nav(type, query), group_type: type,
227
+ def serve_browse(query)
228
+ groups = collect_groups(selector(query), group_by(query), sort_by(query), sort_order(query))
229
+ content = to_markup('pictures_browse', nav: make_nav(query), group_key: group_by(query),
205
230
  filters: selector(query), groups: groups)
206
231
  [206, 'text/html',
207
232
  { content: content, title: title, stylesheets: stylesheets, scripts: scripts }]
@@ -222,28 +247,32 @@ module Intranet
222
247
  ### Servicing of the REST API (raw JSON data & pictures) ###
223
248
  ##########################################################################
224
249
 
225
- def api_list_groups(path, query)
226
- group_type = path.split('/')[2].to_s
227
- @provider.list_groups(group_type, selector(query), sort_by(query), sort_order(query))
228
- end
250
+ def api_group_thumbnail(query)
251
+ raise KeyError unless query.size == 1
229
252
 
230
- def api_group_thumbnail(path, query)
231
- group_type = path.split('/')[2].to_s
232
- pic = @provider.group_thumbnail(group_type, selector(query))
253
+ key, value = query.first
254
+ pic = @provider.group_thumbnail(key, value)
233
255
  if pic.nil?
234
256
  pic = ['image/svg+xml', File.read(File.join(resources_dir, 'www', 'group_thumbnail.svg'))]
235
257
  end
236
258
  pic
237
259
  end
238
260
 
261
+ def api_group_brief(query)
262
+ raise KeyError unless query.size == 1
263
+
264
+ key, value = query.first
265
+ @provider.group_brief(key, value)
266
+ end
267
+
239
268
  def api_list_pictures(query)
240
269
  @provider.list_pictures(selector(query), sort_by(query), sort_order(query))
241
270
  end
242
271
 
243
272
  def serve_api(path, query)
244
273
  case path
245
- when %r{^/groups/} then [200, 'application/json', api_list_groups(path, query).to_json]
246
- when %r{^/group/} then [200, api_group_thumbnail(path, query)].flatten
274
+ when %r{^/group_thumbnail$} then [200, api_group_thumbnail(query)].flatten
275
+ when %r{^/group_brief$} then [200, 'application/json', api_group_brief(query).to_json]
247
276
  when %r{^/pictures$} then [200, 'application/json', api_list_pictures(query).to_json]
248
277
  when %r{^/picture$} then [200, @provider.picture(query)].flatten
249
278
  else [404, '', '']
@@ -8,7 +8,7 @@ module Intranet
8
8
  NAME = 'intranet-pictures'
9
9
 
10
10
  # The version of the gem, according to semantic versionning.
11
- VERSION = '1.1.0'
11
+ VERSION = '2.0.0'
12
12
 
13
13
  # The URL of the gem homepage.
14
14
  HOMEPAGE_URL = 'https://rubygems.org/gems/intranet-pictures'
@@ -1,13 +1,14 @@
1
1
  %section
2
2
  = to_markup 'title_and_breadcrumb', {title: title, nav: nav}
3
3
  %ul.groups
4
- - groups.each do |group|
5
- %li{ title: group['title'] }
6
- %a{ onclick: 'openImagesGallery("' + gallery_url(group_type, group['id'], filters) + '");' }
4
+ - groups.each do |group_name|
5
+ %li{ title: group_name }
6
+ %a{ onclick: 'openImagesGallery("' + gallery_url(group_key, group_name, filters) + '");' }
7
7
  %figure
8
- %div{ style: 'background-image: url("api/group/' + group_type + '?' + group_type + '=' + group['id'] + '")' }
8
+ %div{ style: 'background-image: url("api/group_thumbnail?' + group_key + '=' + group_name + '")' }
9
9
  %figcaption
10
- = group['title']
11
- - if group['brief']
10
+ = group_name
11
+ - group_brief = api_group_brief({ group_key => group_name })
12
+ - unless group_brief.empty?
12
13
  %br
13
- %em= group['brief']
14
+ %em= group_brief
@@ -2,32 +2,34 @@
2
2
  = to_markup 'title_and_breadcrumb', {title: title, nav: nav}
3
3
 
4
4
  - recent_groups.each do |recent|
5
- %h3= I18n.t('pictures.recents.' + recent[:group_type])
5
+ %h3= I18n.t('pictures.recents.' + recent[:group_key])
6
6
  %ul.groups
7
- - recent[:groups].each do |group|
8
- %li{ title: group['title'] }
9
- %a{ onclick: 'openImagesGallery("' + gallery_url(recent[:group_type], group['id']) + '");' }
7
+ - recent[:groups].each do |group_name|
8
+ %li{ title: group_name }
9
+ %a{ onclick: 'openImagesGallery("' + gallery_url(recent[:group_key], group_name) + '");' }
10
10
  %figure
11
- %div{ style: 'background-image: url("api/group/' + recent[:group_type] + '?' + recent[:group_type] + '=' + group['id'] + '")' }
11
+ %div{ style: 'background-image: url("api/group_thumbnail?' + recent[:group_key] + '=' + group_name + '")' }
12
12
  %figcaption
13
- = group['title']
14
- - if group['brief']
13
+ = group_name
14
+ - group_brief = api_group_brief({ recent[:group_key] => group_name })
15
+ - unless group_brief.empty?
15
16
  %br
16
- %em= group['brief']
17
+ %em= group_brief
17
18
  - unless recent[:see_more_url].empty?
18
19
  %p.see_more
19
20
  %a{ href: recent[:see_more_url] }= I18n.t('pictures.see_more')
20
21
 
21
22
  - all_groups.each do |section|
22
- %h3= I18n.t('pictures.browse_by.' + section[:group_type])
23
+ %h3= I18n.t('pictures.browse_by.' + section[:group_key])
23
24
  %ul.groups.wide
24
- - section[:groups].each do |group|
25
- %li{ title: group['title'] }
26
- %a{ href: section[:url_prefix] + '&' + section[:group_type] + '=' + group['id'] }
25
+ - section[:groups].each do |group_name|
26
+ %li{ title: group_name }
27
+ %a{ href: section[:url_prefix] + '&' + section[:group_key] + '=' + group_name }
27
28
  %figure
28
- %div{ style: 'background-image: url("api/group/' + section[:group_type] + '?' + section[:group_type] + '=' + group['id'] + '")' }
29
+ %div{ style: 'background-image: url("api/group_thumbnail?' + section[:group_key] + '=' + group_name + '")' }
29
30
  %figcaption
30
- = group['title']
31
- - if group['brief']
31
+ = group_name
32
+ - group_brief = api_group_brief({ section[:group_key] => group_name })
33
+ - unless group_brief.empty?
32
34
  %br
33
- %em= group['brief']
35
+ %em= group_brief