lentil 0.5.2 → 0.6.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
  SHA1:
3
- metadata.gz: fc8b593e81dc92d835ecb8376fb7d5483c1e8bbe
4
- data.tar.gz: 3695ab310995d17e570cb4ca4335e1f3242f734b
3
+ metadata.gz: d0071e0e9cac7e3e22897146471625cdc522ca8b
4
+ data.tar.gz: d25b8819f50541f248855b0ac6584bad2ce256d7
5
5
  SHA512:
6
- metadata.gz: 50d9a3f4ad056eefbd00e63dc9635a733f0af428345d5282eb06de0177f43d93a35a9134be387e0171ec779fc8272055a12fbc6b86ff3a19b3f11ba9397f4db8
7
- data.tar.gz: ff2ae62d71a0dc740e012166339b3a7be550e290bd881680601f38eace29d8c85c7c1e3e91e753d7cf00ec9b212d0fa6e23f4b1725a3a93fe949db62117fef8d
6
+ metadata.gz: b6fd1f6e993cfa866b1448ba22e0a07a7f5750cc3a527d1a9a2b247c39fcdb324ae97fb177ad4cb4f7a91f0f61cdac0f81a2e12e5ee230920f1adabed2977358
7
+ data.tar.gz: 878f9f2cbadd5fb71b9804c07d2235a90390c13c126086b6cecca2dd6cdbd09992c426e680280bd554485c7b8c62a403b006c757583056a9fb2fdbd1faaa0b89
data/README.md CHANGED
@@ -17,14 +17,18 @@ Although we are using this gem in production, **this gem should be considered an
17
17
 
18
18
  lentil has been tested under Ruby 1.9.3 through 2.2.0.
19
19
 
20
+ > We are currently warning against using MySQL due to issues when encoding emoji. PostgreSQL is preferred, but if this is not an option, you may want to follow [this guide](http://tech.taskrabbit.com/blog/2014/04/24/active-record-mysql-and-emoji/).
21
+
20
22
  ### Create a new Rails app with Rails 3.2.x
21
23
 
22
24
  ```sh
23
- rails new your_app_name
25
+ gem install rails -v '~> 3.2'
26
+ rails _3.2.22_ new your_app_name
24
27
  cd your_app_name
25
28
  ```
29
+ > In the example above, `3.2.22` should be the version of Rails 3.x that is installed by the `gem` command.
26
30
 
27
- ### Add lentil and therubyracer (or another ExecJS runtime) to your Gemfile and `bundle`
31
+ ### Add lentil and therubyracer (or another ExecJS runtime) to your Gemfile and run `bundle update`
28
32
 
29
33
  ```ruby
30
34
  gem 'lentil'
@@ -18,7 +18,7 @@ function listenforpopstate() {
18
18
  // and this doesn't look like an image url
19
19
  // switch to page that matches the url
20
20
  if (!/images\/[0-9]/.test(window.location.pathname)) {
21
- window.location.href = window.location.pathname;
21
+ window.location.href = window.location.pathname;
22
22
  }
23
23
  } else {
24
24
 
@@ -26,7 +26,7 @@ function listenforpopstate() {
26
26
  // but the url looks like an image url
27
27
  // switch to the image page that matches the url
28
28
  if (/images\/[0-9]/.test(window.location.pathname)) {
29
- window.location.href = window.location.pathname;
29
+ window.location.href = window.location.pathname;
30
30
  }
31
31
  }
32
32
  };
@@ -45,28 +45,28 @@ function pushimageurl() {
45
45
  replacementUrl = replacementUrl.replace("//","/");
46
46
  }
47
47
 
48
- // push the url for the displayed image to the browser
49
- window.history.pushState(null, null, replacementUrl);
50
-
51
- Lentil.ga_track(['_trackPageview', replacementUrl]);
52
-
53
- // listen for popstate (back/forward button)
54
- window.onpopstate = function(){
55
- if (/images\/[0-9]/.test(window.location.pathname)) {
56
- // if this url looks like an image show url then switch
57
- // the browser to the displayed url
58
- window.location.href = window.location.pathname;
59
- } else {
60
- // otherwise switch the popcalled state to true
61
- // and close the fancybox
62
- FancyBoxCloseFunctionState.popcalled = true;
63
- $.fancybox.close();
64
- // switch the popcalled flag to false
65
- // and the fancybox visible flag to false
66
- FancyBoxCloseFunctionState.popcalled = false;
67
- FancyBoxCloseFunctionState.fancyboxvisible = false;
68
- }
69
- };
48
+ // push the url for the displayed image to the browser
49
+ window.history.pushState(null, null, replacementUrl);
50
+
51
+ Lentil.ga_track(['_trackPageview', replacementUrl]);
52
+
53
+ // listen for popstate (back/forward button)
54
+ window.onpopstate = function(){
55
+ if (/images\/[0-9]/.test(window.location.pathname)) {
56
+ // if this url looks like an image show url then switch
57
+ // the browser to the displayed url
58
+ window.location.href = window.location.pathname;
59
+ } else {
60
+ // otherwise switch the popcalled state to true
61
+ // and close the fancybox
62
+ FancyBoxCloseFunctionState.popcalled = true;
63
+ $.fancybox.close();
64
+ // switch the popcalled flag to false
65
+ // and the fancybox visible flag to false
66
+ FancyBoxCloseFunctionState.popcalled = false;
67
+ FancyBoxCloseFunctionState.fancyboxvisible = false;
68
+ }
69
+ };
70
70
  }
71
71
 
72
72
  function addfancybox() {
@@ -78,42 +78,38 @@ function addfancybox() {
78
78
  prevEffect : 'none',
79
79
  live : true,
80
80
  loop : false,
81
- minWidth : '250px',
81
+ autoSize : true,
82
+ fitToView: true,
83
+ minWidth : 250,
84
+ scrolling : 'no',
82
85
  type: 'html',
83
86
  helpers : {
84
87
  title : { type : 'inside' },
85
88
  overlay : { locked : false }
86
89
  },
87
90
  aspectRatio : true,
88
- afterLoad: function(current, previous) {
91
+ beforeLoad: function() {
92
+ var img = $(this.element).children(".instagram-img");
89
93
 
90
- // pushing base url so that back/close returns to image gallery
91
- // instead of image show
92
- window.history.pushState(null,null,FancyBoxCloseFunctionState.pathname);
94
+ if($(img).attr("data-media-type") === "video") {
95
+ this.content = '<video class="fancybox-video" controls="controls" height="100%" width="100%" src="' + this.href + '" oncanplay="$.fancybox.update()"></video>';
96
+ } else {
97
+ this.content = '<img class="fancybox-img" src="' + this.href + '" onload="$.fancybox.update()"/>';
98
+ }
99
+ return true;
100
+ },
101
+ afterLoad: function(current, previous) {
102
+ // pushing base url so that back/close returns to image gallery
103
+ // instead of image show
104
+ window.history.pushState(null,null,FancyBoxCloseFunctionState.pathname);
93
105
  },
94
106
  beforeShow : function() {
95
- var img = $(this.element).children(".instagram-img");
96
- if($(img).attr("data-media-type") === "video") {
97
- var video_url = $(img).attr("src");
98
- //this.content = "<video src='" + video_url + "' height='320' width='320' controls='controls'></video>";
99
- $(".fancybox-inner").html('<video controls="controls" height="100%" width="90%" src="' + video_url + '"></video>');
100
- var vid = $(".fancybox-inner").children("video")[0];
101
- vid.oncanplay = function() {
102
- $.fancybox.reposition();
103
- }
104
- }
105
- else {
106
- var image_url = $(img).attr("src");
107
- $(".fancybox-inner").html('<img class="fancybox-image" src="' + image_url + '" />');
108
- }
109
-
110
107
  this.title = $(this.element).next(".text-overlay").html();
111
108
  imageId = $(this.element).parents("div").attr("id");
112
109
  $(".fancybox-wrap").attr('id', imageId);
113
110
  pushimageurl(imageId);
114
111
  },
115
112
  afterShow : function() {
116
-
117
113
  // checks whether browser understands touch events
118
114
  // if so the next/prev buttons are disabled
119
115
  // and swipe down/right is added to advance slides
@@ -130,9 +126,6 @@ function addfancybox() {
130
126
  });
131
127
  }
132
128
 
133
- // adds button handling script to displayed fancybox buttons
134
- buttonhandler();
135
-
136
129
  // this is to check that the fancybox is really visible
137
130
  // afterClose is fired off on fancybox open -- a bug
138
131
  FancyBoxCloseFunctionState.fancyboxvisible = true;
@@ -155,14 +148,14 @@ function addfancybox() {
155
148
  afterClose : function() {
156
149
  if (FancyBoxCloseFunctionState.popcalled === false && FancyBoxCloseFunctionState.fancyboxvisible === true) {
157
150
 
158
- // if after closing the fancybox there is no pop event
159
- // and the fancybox is visible
160
- // (this afterClose event also fires when fancybox opens
161
- // -- a bug we're getting around with this hack)
162
- // switch the flags and point the url at the previous page
163
- // should be an image tile view (recent, popular, staff picks, etc.)
164
- FancyBoxCloseFunctionState.fancyboxvisible = false;
165
- window.history.back();
151
+ // if after closing the fancybox there is no pop event
152
+ // and the fancybox is visible
153
+ // (this afterClose event also fires when fancybox opens
154
+ // -- a bug we're getting around with this hack)
155
+ // switch the flags and point the url at the previous page
156
+ // should be an image tile view (recent, popular, staff picks, etc.)
157
+ FancyBoxCloseFunctionState.fancyboxvisible = false;
158
+ window.history.back();
166
159
  }
167
160
  }
168
161
  });
@@ -1,6 +1,6 @@
1
1
  function buttonhandler() {
2
2
 
3
- $(".like-btn, .flag-confirm").click(function(e) {
3
+ $("body").on("click", ".like-btn, .flag-confirm", function(e) {
4
4
  button = $(this);
5
5
  imageId = $(".fancybox-wrap, .image-show").attr("id");
6
6
  if (!$(button).is(".already-clicked")) {
@@ -20,4 +20,4 @@ function buttonhandler() {
20
20
  }
21
21
  e.preventDefault();
22
22
  });
23
- }
23
+ }
@@ -1,5 +1,5 @@
1
1
  function addimageerrors() {
2
- $(".instagram-img, .battle-img, .fancybox-img").off("error").on("error", function () {
2
+ $(".instagram-img, .battle-img, .fancybox-img, .fancybox-video").off("error").on("error", function () {
3
3
  $(this).parents("div.image-tile, li.image-animate-tile").remove();
4
4
  /*if ($("body.images_animate") || $("body.images_staff_picks_animate")) {
5
5
  addanimatedimages();
@@ -140,6 +140,14 @@ div.images {
140
140
  border-radius: 3px;
141
141
  }
142
142
 
143
+ .fancybox-inner {
144
+ min-width: 250px;
145
+ }
146
+
147
+ .fancybox-nav {
148
+ height:90%;
149
+ }
150
+
143
151
  .pagination .disabled, .pagination .current {
144
152
  color: #000;
145
153
  }
@@ -312,4 +320,4 @@ body.lt-ie8 {
312
320
 
313
321
  body.lt-ie8 div.image-tile {
314
322
  width: 300px;
315
- }
323
+ }
@@ -29,7 +29,7 @@
29
29
  .side-filler { width: fluid(0); }
30
30
 
31
31
  ul {
32
- margin-top: 30px;
32
+ margin-top: 25px;
33
33
  }
34
34
 
35
35
  .navbar .library-brand {
@@ -219,4 +219,4 @@
219
219
 
220
220
  @include breakpoint(124, $label: 'microtile'){
221
221
  .image-tile { width: fluid(8); }
222
- }
222
+ }
@@ -38,7 +38,7 @@ class Lentil::Image < ActiveRecord::Base
38
38
  :do_not_request_donation, :donor_agreement_rejected, :media_type, :video_url, :suppressed
39
39
 
40
40
  attr_protected :original_metadata
41
-
41
+
42
42
  has_many :won_battles, :class_name => "Battle"
43
43
  has_many :losers, :through => :battles
44
44
  has_many :lost_battles, :class_name => "Battle", :foreign_key => "loser_id"
@@ -97,8 +97,8 @@ class Lentil::Image < ActiveRecord::Base
97
97
 
98
98
  def service_tags
99
99
  begin
100
- tag_ids = self.taggings.where(:staff_tag => false).pluck(:tag_id)
101
- tags = Lentil::Tag.find(tag_ids).sort_by(&:name)
100
+ tag_ids = self.taggings.select { |tagging| tagging.staff_tag == false }.map(&:tag_id)
101
+ tags = self.tags.select { |tag| tag_ids.include? tag.id}.sort_by(&:name)
102
102
  rescue
103
103
  Rails.logger.error "Error retrieving service_tags"
104
104
  tags = []
@@ -107,31 +107,19 @@ class Lentil::Image < ActiveRecord::Base
107
107
 
108
108
  def staff_tags
109
109
  begin
110
- tag_ids = self.taggings.where(:staff_tag => true).pluck(:tag_id)
111
- tags = Lentil::Tag.find(tag_ids).sort_by(&:name)
110
+ tag_ids = self.taggings.select { |tagging| tagging.staff_tag == true }.map(&:tag_id)
111
+ tags = self.tags.select { |tag| tag_ids.include? tag.id}.sort_by(&:name)
112
112
  rescue
113
113
  Rails.logger.error "Error retrieving staff_tags"
114
114
  tags = []
115
115
  end
116
116
  end
117
117
 
118
- def available_staff_tags
119
- begin
120
- system_tag_ids = self.taggings.where(:staff_tag => false).pluck(:tag_id)
121
- rescue
122
- Rails.logger.error "Error retrieving staff_tags"
123
- tags = []
124
- else
125
- tags = []
126
- Lentil::Tag.all.each do |tag|
127
- unless system_tag_ids.include? tag.id
128
- tags.push(tag)
129
- end
130
- end
131
-
132
- if tags.length > 0
133
- tags = tags.sort_by(&:name)
134
- end
118
+ def available_staff_tags(all_tags)
119
+ tags = all_tags - (self.tags - self.staff_tags)
120
+
121
+ if tags.length > 0
122
+ tags = tags.sort_by(&:name)
135
123
  end
136
124
  end
137
125
 
@@ -189,7 +177,6 @@ class Lentil::Image < ActiveRecord::Base
189
177
  }
190
178
 
191
179
  state_machine :state, :initial => :pending do
192
-
193
180
  States.each do |name, value|
194
181
  state name, :value => value
195
182
  end
@@ -201,9 +188,8 @@ class Lentil::Image < ActiveRecord::Base
201
188
  event :reject do
202
189
  transition all => :rejected
203
190
  end
204
-
205
191
  end
206
-
192
+
207
193
  def original_metadata=(meta)
208
194
  write_attribute(:original_metadata, meta.to_hash)
209
195
  end
@@ -20,7 +20,9 @@ class Lentil::Tag < ActiveRecord::Base
20
20
  validates_presence_of :name
21
21
 
22
22
  scope :harvestable, where(:lentil_tagsets => {:harvest => true}).includes(:tagsets)
23
-
23
+ scope :not_harvestable, where(:lentil_tagsets => {:harvest => false}).includes(:tagsets)
24
+ scope :no_tagsets, where(:lentil_tagset_assignments => {:tag_id => nil}).includes(:tagset_assignments)
25
+
24
26
  #Stripping tags on write
25
27
  def name=(new_name)
26
28
  write_attribute(:name, new_name.sub(/^#/, ''))
@@ -6,6 +6,7 @@
6
6
  <th>Description</th>
7
7
  <th>Username</th>
8
8
  <th>Service Tags</th>
9
+ <th>Harvesting Tags</th>
9
10
  <th>Staff Tags</th>
10
11
  <th>Staff Like</th>
11
12
  <th>DNR</th>
@@ -31,8 +32,16 @@
31
32
  <td><%= image.service_tags.map{|tag| tag.name}.join(' | ') %>
32
33
  <%= f.input "service_tags", :as => :hidden, :collection => image.service_tags, :wrapper_html => {:style => "list-style: none"} %>
33
34
  </td>
35
+ <td><%= image.service_tags.select{|tag| @harvestable_tag_ids.include? tag.id}.map{|tag| tag.name}.join(' | ') %></td>
34
36
  <td class="moderation_tag">
35
- <%= f.input :tags, :label => false, :as => :select, :collection => image.available_staff_tags, :input_html => {:multiple => true, :class => "chzn-select", :'data-placeholder' => 'Select Tag', :style => "width:190px" }%>
37
+ <% if defined? @tags %>
38
+ <%= f.input :tags, :label => false, :as => :select, :collection => image.available_staff_tags(@tags), :input_html => {:multiple => true, :class => "chzn-select", :'data-placeholder' => 'Select Tag', :style => "width:190px" }%>
39
+ <% else %>
40
+ <% if image.staff_tags.length > 0 %>
41
+ <p><%= image.staff_tags.map{|tag| tag.name}.join(' | ') %></p>
42
+ <% end %>
43
+ <%= link_to('Edit Staff Tags', update_image_admin_lentil_image_path(image)) %>
44
+ <% end %>
36
45
  </td>
37
46
  <td><%= f.input :staff_like, :label => "Staff Like", :wrapper_html => { :class => "moderation_checkbox" } %></td>
38
47
  <td><%= f.input :do_not_request_donation, :label => "Don't request donation", :wrapper_html => { :class => "moderation_checkbox" } %></td>
@@ -7,6 +7,7 @@
7
7
  <th>Description</th>
8
8
  <th>Username</th>
9
9
  <th>All Tags</th>
10
+ <th>Harvesting Tags</th>
10
11
  <th>Moderator</th>
11
12
  <th>Status</th>
12
13
  </tr>
@@ -19,6 +20,7 @@
19
20
  <td><%= image.description %></td>
20
21
  <td><%= image.user.user_name %></td>
21
22
  <td><%= image.tags.map{|tag| tag.name}.join(' | ') %></td>
23
+ <td><%= image.service_tags.select{|tag| @harvestable_tag_ids.include? tag.id}.map{|tag| tag.name}.join(' | ') %></td>
22
24
  <td><%= image.moderator.email if image.moderator %></td>
23
25
  <td><%= image.state_name %></td>
24
26
  <% end -%>
@@ -30,4 +32,4 @@
30
32
  <div class="blank_slate_container">
31
33
  <span class="blank_slate">No Flagging History Found</span>
32
34
  </div>
33
- <% end -%>
35
+ <% end -%>
@@ -0,0 +1,14 @@
1
+ <table class="index_table">
2
+ <thead>
3
+ <tr>
4
+ <th>Stat Name</th>
5
+ <th>Value</th>
6
+ </tr>
7
+ </thead>
8
+ <% @stats.each do |stat| %>
9
+ <tr class=>
10
+ <td><%= stat[:name] %></td>
11
+ <td><%= stat[:value] %></td>
12
+ </tr>
13
+ <% end -%>
14
+ </table>
@@ -1,18 +1,20 @@
1
- <div class="images">
2
- <% @images.each do |image| %>
1
+ <div class="images">
2
+ <% @images.each do |image| %>
3
3
  <div id="image_<%= image.id %>" class="grid__cell image-tile">
4
- <%= link_to url_for(image), 'data-fancybox-href' => image.video_url, 'data-fancybox-group' => "image-tile-gallery", :class => :fancybox do %>
5
- <% unless image.media_type == "video" %>
6
- <%= image_tag(image.jpeg, :class => "instagram-img " + image.id.to_s, :alt => image.description, :data => {:battles_count => image.battles_count, :win_pct => image.win_pct, :popularity => image.popular_score, :staff_like => image.staff_like, :like_votes_count => image.like_votes_count, :media_type => image.media_type}) %>
4
+ <% unless image.media_type == "video" %>
5
+ <%= link_to url_for(image), 'data-fancybox-href' => image.jpeg, 'data-fancybox-group' => "image-tile-gallery", :class => :fancybox do %>
6
+ <%= image_tag(image.jpeg, :class => "instagram-img " + image.id.to_s, :alt => image.description, :data => {:battles_count => image.battles_count, :win_pct => image.win_pct, :popularity => image.popular_score, :staff_like => image.staff_like, :like_votes_count => image.like_votes_count, :media_type => image.media_type}) %>
7
+ <% end %>
7
8
  <% else %>
8
- <%= video_tag(image.video_url, :autoplay => "true", :muted => "true", :loop => "true", :class => "instagram-img " + image.id.to_s, :height => "100%", :width => "100%", :poster => image.jpeg, :data => {:battles_count => image.battles_count, :win_pct => image.win_pct, :popularity => image.popular_score, :staff_like => image.staff_like, :like_votes_count => image.like_votes_count, :media_type => image.media_type}) %>
9
+ <%= link_to url_for(image), 'data-fancybox-href' => image.video_url, 'data-fancybox-group' => "image-tile-gallery", :class => :fancybox do %>
10
+ <%= video_tag(image.video_url, :autoplay => "true", :muted => "true", :loop => "true", :class => "instagram-img-" + image.id.to_s, :class => "instagram-img " + image.id.to_s, :height => "100%", :width => "100%", :poster => image.jpeg, :data => {:battles_count => image.battles_count, :win_pct => image.win_pct, :popularity => image.popular_score, :staff_like => image.staff_like, :like_votes_count => image.like_votes_count, :media_type => image.media_type}) %>
11
+ <% end %>
9
12
  <% end %>
10
- <% end %>
11
13
 
12
- <%= render "/layouts/lentil/image_popup", :image => image %>
13
- <% if params[:controller] == "lentil/thisorthat" %>
14
- <div class="battle-leader-overlay"><%= number_to_percentage(image.win_pct, :precision => 0) %></div>
15
- <% end -%>
14
+ <%= render "/layouts/lentil/image_popup", :image => image %>
15
+ <% if params[:controller] == "lentil/thisorthat" %>
16
+ <div class="battle-leader-overlay"><%= number_to_percentage(image.win_pct, :precision => 0) %></div>
17
+ <% end -%>
16
18
  </div>
17
- <% end -%>
18
- </div>
19
+ <% end -%>
20
+ </div>
@@ -4,10 +4,11 @@
4
4
  <div class="battle-image-wrap grid__cell">
5
5
  <%= semantic_fields_for "image[#{image.id}]", image do |f| %>
6
6
  <div id="image_<%= image.id %>" class="battle-image-tile">
7
- <a href="<%= url_for(image) %>" data-fancybox-href= "<%= image.jpeg %>" class="fancybox">
8
7
  <% unless image.media_type == "video" %>
8
+ <a href="<%= url_for(image) %>" data-fancybox-href= "<%= image.jpeg %>" class="fancybox">
9
9
  <%= image_tag(image.jpeg, :class => "battle-img instagram-img", :data => {:battles_count => image.battles_count, :win_pct => image.win_pct, :popularity => image.popular_score, :staff_like => image.staff_like, :like_votes_count => image.like_votes_count, :media_type => image.media_type}) %>
10
10
  <% else %>
11
+ <a href="<%= url_for(image) %>" data-fancybox-href= "<%= image.video_url %>" class="fancybox">
11
12
  <%= video_tag(image.video_url, :class => "instagram-img " + image.id.to_s, :height => "100%", :width => "100%", :poster => image.jpeg, :controls => "controls", :data => {:battles_count => image.battles_count, :win_pct => image.win_pct, :popularity => image.popular_score, :staff_like => image.staff_like, :like_votes_count => image.like_votes_count, :media_type => image.media_type}) %>
12
13
  <% end %>
13
14
  <div class="battle-image-desc trunc-small"><div class="battle-image-inner-desc"><%= truncate(image.description, :length => 35) %></div></div>
@@ -28,10 +29,11 @@
28
29
  <% @prev_images.each do |image| %>
29
30
  <div class="battle-image-wrap grid__cell" style="background:#e6e6e6">
30
31
  <div id="image_<%= image.id %>" class="battle-image-tile">
31
- <a href="<%= url_for(image) %>" data-fancybox-href= "<%= image.jpeg %>" class="fancybox">
32
32
  <% unless image.media_type == "video" %>
33
+ <a href="<%= url_for(image) %>" data-fancybox-href= "<%= image.jpeg %>" class="fancybox">
33
34
  <%= image_tag(image.jpeg, :class => "battle-img instagram-img", :data => {:battles_count => image.battles_count, :win_pct => image.win_pct, :popularity => image.popular_score, :staff_like => image.staff_like, :like_votes_count => image.like_votes_count, :media_type => image.media_type}) %>
34
35
  <% else %>
36
+ <a href="<%= url_for(image) %>" data-fancybox-href= "<%= image.video_url %>" class="fancybox">
35
37
  <%= video_tag(image.video_url, :class => "instagram-img " + image.id.to_s, :height => "100%", :width => "100%", :poster => image.jpeg, :controls => "controls", :data => {:battles_count => image.battles_count, :win_pct => image.win_pct, :popularity => image.popular_score, :staff_like => image.staff_like, :like_votes_count => image.like_votes_count, :media_type => image.media_type}) %>
36
38
  <% end %>
37
39
  <div class="battle-image-desc trunc-small"><div class="battle-image-inner-desc"><%= truncate(image.description, :length => 35) %></div></div>
@@ -14,4 +14,4 @@ if defined?(ActiveAdmin)
14
14
  column :updated_at
15
15
  end
16
16
  end
17
- end
17
+ end
@@ -2,10 +2,41 @@ if defined?(ActiveAdmin)
2
2
  ActiveAdmin.register Lentil::Image do
3
3
  actions :index, :show
4
4
 
5
- config.batch_actions = false
5
+ config.batch_actions = true
6
6
  config.per_page = 10
7
7
 
8
- filter :state, :as => :select, :collection => proc { Lentil::Image::States }
8
+ batch_action :destroy, false
9
+
10
+ batch_action :approve_all do |ids|
11
+ images = Lentil::Image.where(id: ids)
12
+ total_images = images.size
13
+ image_counter = 0
14
+ errors = []
15
+
16
+ images.each do |image|
17
+ second_moderation = true
18
+ unless image.moderator_id.nil?
19
+ second_moderation = false
20
+ end
21
+
22
+ begin
23
+ image.update_attributes!(:state => 1, :moderator => current_admin_user, :moderated_at => DateTime.now,
24
+ :second_moderation => second_moderation)
25
+ rescue Exception => e
26
+ errors << "image_id #{image.id}: #{e.message}"
27
+ next
28
+ end
29
+
30
+ image_counter += 1
31
+ end
32
+
33
+ if errors.length > 0
34
+ redirect_to collection_path, notice: "#{image_counter} #{'Image'.pluralize(image_counter)} approved (out of #{total_images})", alert: errors.join('<br>').html_safe
35
+ else
36
+ redirect_to collection_path, notice: "#{image_counter} #{'Image'.pluralize(image_counter)} approved (out of #{total_images})"
37
+ end
38
+ end
39
+
9
40
  filter :suppressed
10
41
  filter :media_type, :as => :select
11
42
  filter :user_user_name, :as => :string, :label => "Username"
@@ -22,16 +53,40 @@ if defined?(ActiveAdmin)
22
53
  filter :url, :label => "Service URL"
23
54
  filter :id
24
55
 
56
+ scope :all
57
+ scope :new, :default => true do |images|
58
+ images.where(:state => Lentil::Image::States[:pending])
59
+ end
60
+ scope :approved do |images|
61
+ images.where(:state => Lentil::Image::States[:approved])
62
+ end
63
+ scope :rejected do |images|
64
+ images.where(:state => Lentil::Image::States[:rejected])
65
+ end
66
+ scope :skipped do |images|
67
+ images.where(:state => Lentil::Image::States[:pending]).where("moderator_id IS NOT NULL")
68
+ end
69
+ # scope :flagged do |images|
70
+ # # images.where(:state => Lentil::Image::States[:pending]).where("moderator_id IS NOT NULL")
71
+ # images.includes(:user, :tags, :taggings, :flags).joins(:flags).where(:second_moderation => false).uniq.all
72
+ # end
73
+
25
74
  action_item :only => :show do
26
75
  link_to('Update Image', update_image_admin_lentil_image_path(lentil_image))
27
76
  end
28
77
  action_item { link_to "Moderate New", moderate_admin_lentil_images_path }
29
78
  action_item { link_to "Moderate Skipped", moderate_skipped_admin_lentil_images_path }
30
79
  action_item { link_to "Moderate Flagged", moderate_flagged_admin_lentil_images_path }
80
+ action_item { link_to "Moderate Approved", moderate_approved_admin_lentil_images_path }
81
+ action_item { link_to "Moderate Rejected", moderate_rejected_admin_lentil_images_path }
31
82
  action_item { link_to "Flagging History", flagging_history_admin_lentil_images_path }
32
83
  action_item { link_to "Add Instagram Image", manual_input_admin_lentil_images_path }
33
84
 
34
85
  index do
86
+ harvestable_tag_ids = Lentil::Tag.harvestable.map(&:id)
87
+ if current_scope.name == 'New'
88
+ selectable_column
89
+ end
35
90
  column "Image" do |image|
36
91
  unless image.media_type == "video"
37
92
  link_to(image_tag(image.image_url, :class => "moderation_thumbnail"), admin_lentil_image_path(image))
@@ -50,6 +105,9 @@ if defined?(ActiveAdmin)
50
105
  column "All Tags" do |image|
51
106
  image.tags.map{|tag| tag.name}.join(' | ')
52
107
  end
108
+ column "Harvesting Tags" do |image|
109
+ image.service_tags.select{|tag| harvestable_tag_ids.include? tag.id}.map{|tag| tag.name}.join(' | ')
110
+ end
53
111
  column "Likes", :like_votes_count
54
112
  column :staff_like
55
113
  column "Battles", :battles_count, :sortable => false
@@ -68,6 +126,7 @@ if defined?(ActiveAdmin)
68
126
  end
69
127
 
70
128
  show :title => :id do |image|
129
+ harvestable_tag_ids = Lentil::Tag.harvestable.map(&:id)
71
130
  attributes_table do
72
131
  row :id
73
132
  row :description
@@ -90,6 +149,13 @@ if defined?(ActiveAdmin)
90
149
  "Image has not been tagged."
91
150
  end
92
151
  end
152
+ row "Harvesting Tags" do |image|
153
+ unless image.service_tags.select{|tag| harvestable_tag_ids.include? tag.id}.empty?
154
+ image.service_tags.select{|tag| harvestable_tag_ids.include? tag.id}.map{|tag| tag.name}.join(' | ')
155
+ else
156
+ "Image has no harvesting tags."
157
+ end
158
+ end
93
159
  row :staff_like
94
160
  row :do_not_request_donation
95
161
  row :donor_agreement_submitted_date
@@ -99,51 +165,88 @@ if defined?(ActiveAdmin)
99
165
  image.state_name
100
166
  end
101
167
  row :image do
102
- unless image.media_type == "video"
103
- link_to(image_tag(image.image_url), admin_lentil_image_path(image))
104
- else
105
- video_tag(image.video_url, controls: true, size: "640x640")
106
- end
168
+ unless image.media_type == "video"
169
+ link_to(image_tag(image.image_url), admin_lentil_image_path(image))
170
+ else
171
+ video_tag(image.video_url, controls: true, size: "640x640")
172
+ end
107
173
  end
108
174
  end
109
175
  active_admin_comments
110
176
  end
111
177
 
112
178
  controller do
179
+ def scoped_collection
180
+ super.includes :user, :taggings, :tags
181
+ end
182
+
183
+ # TODO: This method may need optimization
113
184
  def update_images(images, images_params, second_moderation)
185
+ total_images = images.size
186
+ image_counter = 0
187
+ errors = []
188
+
114
189
  images.each do |image|
115
190
  image_params = images_params[image.id.to_s]
116
191
 
117
- incoming_tag_ids = image_params['tag_ids'].reject(&:empty?)
118
- existing_tag_ids = []
119
- service_tag_ids = []
192
+ if image_params.key?(:tag_ids)
193
+ incoming_tag_ids = image_params['tag_ids'].reject(&:empty?)
194
+ existing_tag_ids = []
195
+ service_tag_ids = []
120
196
 
121
- image.taggings.each do |tagging|
122
- existing_tag_ids << tagging[:tag_id]
123
- if tagging[:staff_tag] == false
124
- service_tag_ids << tagging[:tag_id]
197
+ image.taggings.each do |tagging|
198
+ existing_tag_ids << tagging[:tag_id]
199
+ if tagging[:staff_tag] == false
200
+ service_tag_ids << tagging[:tag_id]
201
+ end
125
202
  end
126
- end
127
203
 
128
- new_tag_ids = incoming_tag_ids - existing_tag_ids
129
- tag_ids_to_keep = incoming_tag_ids - new_tag_ids + service_tag_ids
204
+ new_tag_ids = incoming_tag_ids - existing_tag_ids
205
+ tag_ids_to_keep = incoming_tag_ids - new_tag_ids + service_tag_ids
130
206
 
131
- new_taggings = []
132
- new_tag_ids.each do |id|
133
- new_taggings << image.taggings.build(:tag_id => id, :staff_tag => true)
207
+ new_taggings = []
208
+ new_tag_ids.each do |id|
209
+ new_taggings << image.taggings.build(:tag_id => id, :staff_tag => true)
210
+ end
211
+
212
+ taggings_to_keep = image.taggings.select{ |tagging| tag_ids_to_keep.include? tagging.tag_id}
213
+ taggings = new_taggings + taggings_to_keep
214
+
215
+ # Save Updated Image with new tags
216
+ begin
217
+ image.update_attributes!(:state => image_params['state'], :taggings => taggings, :staff_like => image_params['staff_like'],
218
+ :moderator => current_admin_user, :moderated_at => DateTime.now, :second_moderation => second_moderation,
219
+ :do_not_request_donation => image_params['do_not_request_donation'], :suppressed => image_params['suppressed'])
220
+ rescue Exception => e
221
+ errors << "image_id #{image.id}: #{e.message}"
222
+ next
223
+ end
224
+ else
225
+ # Save Updated Image with same tags
226
+ begin
227
+ image.update_attributes!(:state => image_params['state'], :staff_like => image_params['staff_like'],
228
+ :moderator => current_admin_user, :moderated_at => DateTime.now, :second_moderation => second_moderation,
229
+ :do_not_request_donation => image_params['do_not_request_donation'], :suppressed => image_params['suppressed'])
230
+ rescue Exception => e
231
+ errors << "image_id #{image.id}: #{e.message}"
232
+ next
233
+ end
134
234
  end
135
235
 
136
- taggings_to_keep = image.taggings.where(:tag_id => tag_ids_to_keep)
137
- taggings = new_taggings + taggings_to_keep
236
+ image_counter += 1
237
+ end
138
238
 
139
- image.update_attributes!(:state => image_params['state'], :taggings => taggings, :staff_like => image_params['staff_like'],
140
- :moderator => current_admin_user, :moderated_at => DateTime.now, :second_moderation => second_moderation,
141
- :do_not_request_donation => image_params['do_not_request_donation'], :suppressed => image_params['suppressed'])
239
+ if errors.length > 0
240
+ redirect_to :back, notice: "#{image_counter} #{'Image'.pluralize(image_counter)} moderated (out of #{total_images})", alert: errors.join('<br>').html_safe
241
+ else
242
+ redirect_to :back, notice: "#{image_counter} #{'Image'.pluralize(image_counter)} moderated (out of #{total_images})"
142
243
  end
143
244
  end
144
245
  end
145
246
 
146
247
  member_action :update_image do
248
+ @tags = Lentil::Tag.all
249
+ @harvestable_tag_ids = Lentil::Tag.harvestable.map(&:id)
147
250
  id = params['id']
148
251
  @second_moderation = false
149
252
  @images = Lentil::Image.where(id: id)
@@ -151,42 +254,51 @@ if defined?(ActiveAdmin)
151
254
  end
152
255
 
153
256
  collection_action :moderate do
257
+ @harvestable_tag_ids = Lentil::Tag.harvestable.map(&:id)
154
258
  @second_moderation = false
155
- @images = Lentil::Image.where(state: Lentil::Image::States[:pending], moderator_id: nil).paginate(:page => params[:page], :per_page => 10)
259
+ @images = Lentil::Image.includes(:user, :taggings, :tags).where(state: Lentil::Image::States[:pending], moderator_id: nil).paginate(:page => params[:page], :per_page => 10)
260
+ end
261
+
262
+ collection_action :moderate_approved do
263
+ @harvestable_tag_ids = Lentil::Tag.harvestable.map(&:id)
264
+ @second_moderation = false
265
+ @images = Lentil::Image.includes(:user, :taggings, :tags).where(state: Lentil::Image::States[:approved]).paginate(:page => params[:page], :per_page => 10)
266
+ render "/admin/lentil_images/moderate"
267
+ end
268
+
269
+ collection_action :moderate_rejected do
270
+ @harvestable_tag_ids = Lentil::Tag.harvestable.map(&:id)
271
+ @second_moderation = false
272
+ @images = Lentil::Image.includes(:user, :taggings, :tags).where(state: Lentil::Image::States[:rejected]).paginate(:page => params[:page], :per_page => 10)
273
+ render "/admin/lentil_images/moderate"
156
274
  end
157
275
 
158
276
  collection_action :moderate_skipped do
277
+ @harvestable_tag_ids = Lentil::Tag.harvestable.map(&:id)
159
278
  @second_moderation = false
160
- @images = Lentil::Image.where(state: Lentil::Image::States[:pending]).where("moderator_id IS NOT NULL").paginate(:page => params[:page], :per_page => 10)
279
+ @images = Lentil::Image.includes(:user, :taggings, :tags).where(state: Lentil::Image::States[:pending]).where("moderator_id IS NOT NULL").paginate(:page => params[:page], :per_page => 10)
161
280
  render "/admin/lentil_images/moderate"
162
281
  end
163
282
 
164
283
  collection_action :moderate_flagged do
284
+ @harvestable_tag_ids = Lentil::Tag.harvestable.map(&:id)
165
285
  @second_moderation = true
166
- @images = Lentil::Image.joins(:flags).group("lentil_images.id").having("count(lentil_flags.id) > 0").where(:second_moderation => false).paginate(:page => params[:page], :per_page => 10)
286
+ temp_images = Lentil::Image.includes(:user, :tags, :taggings, :flags).joins(:flags).where(:second_moderation => false).uniq.all
287
+ @images = Kaminari.paginate_array(temp_images).page(params[:page]).per(10)
167
288
  render "/admin/lentil_images/moderate"
168
289
  end
169
290
 
170
291
  collection_action :do_moderation, :method => :post do
171
- images = Lentil::Image.find(params[:image].keys)
292
+ images = Lentil::Image.find(params[:image].keys, :include => [:user, :taggings, :tags])
172
293
  images_params = params[:image]
173
294
  second_moderation = params[:moderation]['second_moderation']
174
-
175
- begin
176
- update_images(images, images_params, second_moderation)
177
- rescue => e
178
- message = "Error moderating images: " + e.to_s
179
- redirect_to :back, :flash => {:error => message}
180
- else
181
- number_of_images = params['image'].size
182
- plural = 'image'.pluralize(number_of_images)
183
- message = number_of_images.to_s + " " + plural + " moderated."
184
- redirect_to :back, notice: message
185
- end
295
+ update_images(images, images_params, second_moderation)
186
296
  end
187
297
 
188
298
  collection_action :flagging_history do
189
- @images = Lentil::Image.joins(:flags).group("lentil_images.id").having("count(lentil_flags.id) > 0").paginate(:page => params[:page], :per_page => 10)
299
+ @harvestable_tag_ids = Lentil::Tag.harvestable.map(&:id)
300
+ temp_images = Lentil::Image.includes(:user, :tags, :flags, :moderator).joins(:flags).uniq.all
301
+ @images = Kaminari.paginate_array(temp_images).page(params[:page]).per(10)
190
302
  end
191
303
 
192
304
  collection_action :manual_input do
@@ -0,0 +1,34 @@
1
+ ActiveAdmin.register_page "Stats" do
2
+ content do
3
+ render partial: 'stats'
4
+ end
5
+
6
+ controller do
7
+ def index
8
+ stats = []
9
+
10
+ images = Lentil::Image.all
11
+ battles = Lentil::Battle.count
12
+ like_votes = Lentil::LikeVote.count
13
+ users = Lentil::User.count
14
+ tags = Lentil::Tag.count
15
+ taggings = Lentil::Tagging.count
16
+
17
+ submitted_agreements = images.map(&:donor_agreement_submitted_date).compact.count
18
+ rejected_agreements = images.map(&:donor_agreement_rejected).compact.count
19
+ accepted_aggrements = submitted_agreements - rejected_agreements
20
+
21
+ stats << {name: 'Number of Images', value: images.count}
22
+ stats << {name: 'Number of Battles', value: battles}
23
+ stats << {name: 'Number of Like Votes', value: like_votes}
24
+ stats << {name: 'Number of Users', value: users}
25
+ stats << {name: 'Number of Submitted Donor Agreements', value: submitted_agreements}
26
+ stats << {name: 'Number of Accepted Donor Agreements (implicit)', value: accepted_aggrements}
27
+ stats << {name: 'Number of Rejected Donor Agreements (explicit)', value: rejected_agreements}
28
+ stats << {name: 'Number of Unique Tags', value: tags}
29
+ stats << {name: 'Number of Taggings', value: taggings}
30
+
31
+ @stats = stats
32
+ end
33
+ end
34
+ end
@@ -6,13 +6,34 @@ if defined?(ActiveAdmin)
6
6
  config.sort_order = "name_asc"
7
7
 
8
8
  filter :name
9
+ filter :tagsets_title, :as => :string, :label => "Tagsets"
10
+
11
+ scope :all, :default => true
12
+ scope "Harvesting", :harvestable
13
+ scope "Not Harvesting", :not_harvestable
14
+ scope "Not in a Tagset", :no_tagsets
9
15
 
10
16
  index :download_links => false do
17
+ harvestable_ids = Lentil::Tag.harvestable.map(&:id)
18
+
11
19
  column :id
12
20
  column :name
21
+ column "Harvestable" do |tag|
22
+ if harvestable_ids.include?(tag.id)
23
+ "True"
24
+ else
25
+ "False"
26
+ end
27
+ end
13
28
  column "Tagsets" do |tag|
14
29
  tag.tagsets.sort_by(&:title).map{ |t| t.title}.join(' | ')
15
30
  end
16
31
  end
32
+
33
+ controller do
34
+ def scoped_collection
35
+ super.includes :taggings, :tagsets
36
+ end
37
+ end
17
38
  end
18
- end
39
+ end
@@ -6,6 +6,7 @@ if defined?(ActiveAdmin)
6
6
 
7
7
  filter :title
8
8
  filter :description
9
+ filter :tags_name, :collection => proc {Lentil::Tag.all.sort_by(&:name)}, :as => :string, :label => "Tags"
9
10
 
10
11
  scope :all
11
12
  scope :harvesting, :default => true do |tagsets|
@@ -43,9 +44,11 @@ if defined?(ActiveAdmin)
43
44
  f.input :title
44
45
  f.input :description
45
46
  f.input :tags, :input_html => {:class => [:"chzn-select"]}, :collection => Lentil::Tag.all.sort_by(&:name)
46
- f.input :harvest
47
+ f.input :harvest do |harvest|
48
+ harvest.capitalize
49
+ end
47
50
  end
48
51
  f.actions
49
52
  end
50
53
  end
51
- end
54
+ end
@@ -1,3 +1,3 @@
1
1
  module Lentil
2
- VERSION = "0.5.2"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -4,7 +4,6 @@ sqlite: &sqlite
4
4
 
5
5
  mysql: &mysql
6
6
  adapter: mysql2
7
- encoding: utf8
8
7
  username: travis
9
8
  password:
10
9
  database: lentil_<%= Rails.env %>
@@ -20,6 +19,7 @@ defaults: &defaults
20
19
  pool: 5
21
20
  timeout: 5000
22
21
  host: 127.0.0.1
22
+ encoding: utf8
23
23
  <<: *<%= ENV['DB'] || "sqlite" %>
24
24
 
25
25
  development:
@@ -29,4 +29,4 @@ test:
29
29
  <<: *defaults
30
30
 
31
31
  production:
32
- <<: *defaults
32
+ <<: *defaults
@@ -11,6 +11,12 @@ Dummy::Application.configure do
11
11
  config.serve_static_assets = true
12
12
  config.static_cache_control = "public, max-age=3600"
13
13
 
14
+ # Don't fallback to assets pipeline if a precompiled asset is missed
15
+ #config.assets.compile = false
16
+
17
+ # Generate digests for assets URLs
18
+ #config.assets.digest = true
19
+
14
20
  # Log error messages when you accidentally call methods on nil
15
21
  config.whiny_nils = true
16
22
 
@@ -12,10 +12,10 @@ class ImageModalTest < ActionDispatch::IntegrationTest
12
12
  test "should see a modal when clicking on an image" do
13
13
  visit lentil.images_path
14
14
  assert page.has_no_content?('six #hunttesting')
15
- assert page.has_no_selector?('.fancybox-image')
15
+ assert page.has_no_selector?('.fancybox-img')
16
16
  # all('.fancybox').first.click
17
17
  find('.fancybox', match: :first).click
18
18
  assert page.has_content?('six #hunttesting')
19
- assert page.has_selector?('.fancybox-image')
19
+ assert page.has_selector?('.fancybox-img')
20
20
  end
21
21
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lentil
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Casden
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2015-06-18 00:00:00.000000000 Z
14
+ date: 2015-08-26 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rails
@@ -271,14 +271,14 @@ dependencies:
271
271
  requirements:
272
272
  - - "~>"
273
273
  - !ruby/object:Gem::Version
274
- version: 5.0.5
274
+ version: 5.1.0
275
275
  type: :runtime
276
276
  prerelease: false
277
277
  version_requirements: !ruby/object:Gem::Requirement
278
278
  requirements:
279
279
  - - "~>"
280
280
  - !ruby/object:Gem::Version
281
- version: 5.0.5
281
+ version: 5.1.0
282
282
  - !ruby/object:Gem::Dependency
283
283
  name: google-analytics-rails
284
284
  requirement: !ruby/object:Gem::Requirement
@@ -609,6 +609,7 @@ files:
609
609
  - app/views/admin/lentil_images/flagging_history.html.erb
610
610
  - app/views/admin/lentil_images/manual_input.html.erb
611
611
  - app/views/admin/lentil_images/moderate.html.erb
612
+ - app/views/admin/stats/_stats.html.erb
612
613
  - app/views/layouts/lentil/_apple_touch_icons.html.erb
613
614
  - app/views/layouts/lentil/_error.html.erb
614
615
  - app/views/layouts/lentil/_flag_button.html.erb
@@ -703,6 +704,7 @@ files:
703
704
  - lib/lentil/admin/dashboard.rb
704
705
  - lib/lentil/admin/flags.rb
705
706
  - lib/lentil/admin/images.rb
707
+ - lib/lentil/admin/stats.rb
706
708
  - lib/lentil/admin/tags.rb
707
709
  - lib/lentil/admin/tagsets.rb
708
710
  - lib/lentil/admin/user.rb