lentil 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -0
  3. data/app/assets/javascripts/lentil/addfancybox.js +3 -1
  4. data/app/assets/javascripts/lentil/iframe.js +117 -0
  5. data/app/assets/javascripts/lentil/thisorthat.js.erb +18 -20
  6. data/app/assets/stylesheets/lentil/iframe.css.scss +26 -0
  7. data/app/controllers/lentil/images_controller.rb +4 -0
  8. data/app/controllers/lentil/thisorthat_controller.rb +6 -4
  9. data/app/models/lentil/image.rb +16 -6
  10. data/app/views/layouts/lentil/iframe.html.erb +30 -0
  11. data/app/views/lentil/images/iframe.html.erb +9 -0
  12. data/config/routes.rb +1 -0
  13. data/lib/generators/lentil/install_generator.rb +18 -3
  14. data/lib/generators/lentil/templates/README.md +6 -0
  15. data/lib/lentil/instagram_harvester.rb +2 -2
  16. data/lib/lentil/version.rb +1 -1
  17. data/test/dummy/config/application.rb +6 -0
  18. data/test/fixtures/lentil/images.yml +84 -84
  19. data/test/functional/lentil/images_controller_test.rb +5 -0
  20. data/test/functional/lentil/photographers_controller_test.rb +1 -1
  21. data/test/integration/lentil/images_index_test.rb +2 -3
  22. data/test/integration/lentil/javascript/event_tracking_battle_test.rb +1 -2
  23. data/test/integration/lentil/javascript/image_modal_test.rb +2 -2
  24. data/test/vcr_cassettes/battle_images.yml +190 -135
  25. data/test/vcr_cassettes/battle_images_events.yml +123 -167
  26. data/test/vcr_cassettes/instagram_bad_image_check.yml +24 -21
  27. data/test/vcr_cassettes/instagram_good_image_check.yml +160 -15
  28. data/test/vcr_cassettes/instagram_image_harvest.yml +1990 -1950
  29. data/test/vcr_cassettes/instagram_oembed.yml +18 -9
  30. data/vendor/assets/javascripts/imagesloaded/jquery.imagesloaded.min.js +888 -3
  31. metadata +15 -12
  32. data/lib/generators/lentil/templates/devise.rb +0 -232
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2d44b83634b22f894a3ab4c92eb52724edd830d2
4
- data.tar.gz: 3cd9d69ab0aafa2133af86a2971b0c93db661aad
3
+ metadata.gz: 6eb56f9468aa49f44f97b76acb8713076fd16845
4
+ data.tar.gz: 9d8b405b398bbe5cb2158ff23413458e3fd8c140
5
5
  SHA512:
6
- metadata.gz: db2ea9abc4a69a3653824331911fc3a02293ea6b17558b903012464ad7b2982f3e8846e3dee26d1552c300a05ca98033ded401ad1998ca932568af7d12e08037
7
- data.tar.gz: fdb53dccd0ce72c218875884b41f929b9ff6b094f8138fdd8ba2bcf44bd8c8a0130eddf45ccb0291f1ea97f115b8b8665c981895174bb7f739b99f847e62b011
6
+ metadata.gz: 4c725f7fe7d23d9c408bb7c3f10a739a02034d414ee32a5c6011d781b150d7529a9497fab675a0de8fcb624443d75d87570d169c17070d642d014e5510794b35
7
+ data.tar.gz: 5ee673035086d54b67b36d63ed47a1cdbe3279361840653234b76cb4755bde61c7e8a4c7b875467fde72e2f8af08f3bd40b2f7f5beadde342af68ef5e4c599ab
data/README.md CHANGED
@@ -135,6 +135,16 @@ div.header {
135
135
  }
136
136
  ```
137
137
 
138
+ ## Special displays
139
+
140
+ ### Embeddable iframe view
141
+
142
+ This is a simple responsive non-interactive image grid that is intended to be embedded as an iframe. You can find this at `http://YOUR_HOST/images/iframe`.
143
+
144
+ ### Large animated view
145
+
146
+ This is an example of an animated image grid that is designed for non-interactive displays. We have used customized versions of this on e-boards as well as very large video walls. This view will require some customization based on your project and target display. You can find this at `http://YOUR_HOST/images/animate`.
147
+
138
148
  ## Testing
139
149
 
140
150
  - Install all of the dependencies:
@@ -78,8 +78,10 @@ function addfancybox() {
78
78
  prevEffect : 'none',
79
79
  loop : false,
80
80
  minWidth : '250px',
81
+ type: 'image',
81
82
  helpers : {
82
- title : { type : 'inside' }
83
+ title : { type : 'inside' },
84
+ overlay : { locked : false }
83
85
  },
84
86
  afterLoad: function(current, previous) {
85
87
 
@@ -0,0 +1,117 @@
1
+ (function () {
2
+ var Iframe = {
3
+ init: function () {
4
+ this.buildFrame();
5
+ this.attachEvents();
6
+ },
7
+ attachEvents: function () {
8
+ var self = this,
9
+ images;
10
+
11
+ // Remove images that error out
12
+ images = document.getElementsByClassName('instagram-img');
13
+ for (var i = 1; i < images.length; i++) {
14
+ images[i].addEventListener('error', function (e) {
15
+ e.srcElement.parentNode.remove();
16
+ }, false);
17
+ }
18
+
19
+ // Respond to viewport changes
20
+ window.onresize = function (event) {
21
+ self.buildFrame();
22
+ };
23
+ },
24
+ // Sorting utility based on diff
25
+ compare: function (a,b) {
26
+ if (a.diff < b.diff) {
27
+ return -1;
28
+ }
29
+
30
+ if (a.diff > b.diff) {
31
+ return 1;
32
+ }
33
+
34
+ return 0;
35
+ },
36
+ // Get the range of possible number of columns based on image size
37
+ calcColumns: function(least, most) {
38
+ var possibleColumns = [];
39
+
40
+ for (var i = least; i < most; i++) {
41
+ if (possibleColumns.indexOf(i) === -1) {
42
+ possibleColumns.push(i);
43
+ }
44
+ }
45
+
46
+ return possibleColumns;
47
+ },
48
+ // Using columns, determine maximum floored height based on
49
+ // the size of the square image. Value represents the difference
50
+ // between the floored height of rows and the total available height
51
+ calcOptimumLayout: function (possibleColumns, width, height) {
52
+ var self = this,
53
+ layouts = [];
54
+
55
+ possibleColumns.forEach(function (columns) {
56
+ var imageSide,
57
+ rows;
58
+
59
+ imageSide = width/columns;
60
+ rows = Math.floor(height/imageSide);
61
+
62
+ layouts.push({
63
+ columns: columns,
64
+ rows: rows,
65
+ diff: height - (imageSide * rows),
66
+ visibleHeight: rows * Math.floor(imageSide)
67
+ });
68
+ });
69
+
70
+ return layouts.sort(self.compare)[0];
71
+ },
72
+ buildFrame: function () {
73
+ var self = this,
74
+ height,
75
+ images,
76
+ largestImage,
77
+ layout,
78
+ leastColumns,
79
+ mostColumns,
80
+ percent,
81
+ possibleColumns,
82
+ smallestImage,
83
+ width;
84
+
85
+ // Width and height of iFrame
86
+ width = window.innerWidth;
87
+ height = window.innerHeight;
88
+
89
+ // Acceptable image sizes
90
+ smallestImage = 64;
91
+ largestImage = 97;
92
+
93
+ mostColumns = Math.ceil(width/smallestImage);
94
+ leastColumns = Math.ceil(width/largestImage);
95
+ possibleColumns = self.calcColumns(leastColumns, mostColumns);
96
+ layout = self.calcOptimumLayout(possibleColumns, width, height);
97
+
98
+ // Calculate the percent based on the number of columns
99
+ percent = 100 / layout.columns;
100
+
101
+ // Set width of images to build layout
102
+ images = document.getElementsByClassName('iframe-tile');
103
+ for (var i = 0; i < images.length; i++) {
104
+ images[i].style.width = String(percent) + '%';
105
+ }
106
+
107
+ // Set height of wrapper div for overflow
108
+ document.getElementById('iframe-wrapper').style.height = layout.visibleHeight + 'px';
109
+ }
110
+ };
111
+
112
+ document.onreadystatechange = function () {
113
+ if (document.readyState == "interactive") {
114
+ Iframe.init();
115
+ }
116
+ };
117
+ }());
@@ -20,11 +20,12 @@
20
20
  };
21
21
 
22
22
  $(document).ready(function() {
23
- $('.battle-inner:eq(0)').imagesLoaded(function($images, $proper, $broken) {
24
- if ($broken.length > 0) {
25
- $('.battle-wrapper:eq(0)').replaceWith(ERROR_TEXT);
26
- }
27
- });
23
+ $('.battle-inner:eq(0)').imagesLoaded()
24
+ .fail(function (instance) {
25
+ if (instance.hasAnyBroken) {
26
+ $('.battle-wrapper:eq(0)').replaceWith(ERROR_TEXT);
27
+ }
28
+ })
28
29
  });
29
30
 
30
31
  $(document).on('ajax:beforeSend', function (evt, xhr, settings) {
@@ -63,19 +64,8 @@
63
64
  // Insert new images into hidden div
64
65
  $('.battle-inner:eq(1)').replaceWith(data);
65
66
 
66
- // Once images are loaded, execute callback
67
- $('.battle-inner:eq(1)').imagesLoaded(function($images, $proper, $broken) {
68
- var wrap;
69
-
70
- if ($broken.length > 0) {
71
- // Insert error text into DOM
72
- $('.battle-wrapper:eq(0)').replaceWith(ERROR_TEXT);
73
- $('.battle-wrapper:eq(0)').show();
74
-
75
- // Hide Spinner
76
- $('#spinner-overlay').hide();
77
- BATTLE_SPINNER.stop();
78
- } else {
67
+ $('.battle-inner:eq(1)').imagesLoaded()
68
+ .done(function () {
79
69
  // Remove old images
80
70
  $('.battle-wrapper:eq(0)').remove();
81
71
 
@@ -90,8 +80,16 @@
90
80
  wrap = '<div class="wrapper battle-wrapper" style="display:none">' +
91
81
  '<div class="grid battle-inner"></div></div>';
92
82
  $(wrap).insertAfter('.battle-wrapper:eq(0)');
93
- }
94
- });
83
+ }).fail(function () {
84
+ // Insert error text into DOM
85
+ $('.battle-wrapper:eq(0)').replaceWith(ERROR_TEXT);
86
+ $('.battle-wrapper:eq(0)').show();
87
+
88
+ // Hide Spinner
89
+ $('#spinner-overlay').hide();
90
+ BATTLE_SPINNER.stop();
91
+ })
92
+
95
93
  }).on('ajax:error', function (evt, xhr, status) {
96
94
  var error,
97
95
  errors,
@@ -0,0 +1,26 @@
1
+ @import 'breakpoint/sass/framework';
2
+
3
+ // Styles for iframe view
4
+ body.lentil-images_iframe {
5
+ background: none;
6
+ line-height: 0;
7
+ margin: 0;
8
+ }
9
+
10
+ .lentil-images_iframe {
11
+ img {
12
+ margin: 0;
13
+ }
14
+
15
+ #iframe-wrapper {
16
+ width: 100%;
17
+ overflow: hidden;
18
+ }
19
+
20
+ .iframe-tile {
21
+ float: left;
22
+ width: 100%;
23
+ margin: 0;
24
+ padding: 0;
25
+ }
26
+ }
@@ -57,5 +57,9 @@ module Lentil
57
57
  render 'animate'
58
58
  end
59
59
 
60
+ def iframe
61
+ @images = Image.includes(:user).approved.recent.limit(125)
62
+ render :action => "iframe", :layout => "lentil/iframe"
63
+ end
60
64
  end
61
65
  end
@@ -6,10 +6,12 @@ module Lentil
6
6
 
7
7
  def test_urls(images, quantity)
8
8
  image = images.selecting{ |i|
9
- url = URI.parse(i.jpeg)
10
- req = Net::HTTP.new(url.host, url.port)
11
- res = req.request_head(url.path)
12
- res.code == '200'
9
+ begin
10
+ res = OEmbed::Providers::Instagram.get(i.url)
11
+ true
12
+ rescue
13
+ false
14
+ end
13
15
  }.first(quantity)
14
16
  end
15
17
 
@@ -138,16 +138,26 @@ class Lentil::Image < ActiveRecord::Base
138
138
  self.wins_count + self.losses_count
139
139
  end
140
140
 
141
+ # legacy
141
142
  def image_url
142
- if long_url.blank?
143
- url + 'media/?size=l'
144
- else
145
- long_url
146
- end
143
+ large_url
147
144
  end
148
145
 
146
+ # legacy
149
147
  def jpeg
150
- image_url
148
+ large_url
149
+ end
150
+
151
+ def large_url
152
+ url + 'media/?size=l'
153
+ end
154
+
155
+ def medium_url
156
+ url + 'media/?size=m'
157
+ end
158
+
159
+ def thumbnail_url
160
+ url + 'media/?size=t'
151
161
  end
152
162
 
153
163
  States = {
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= yield(:title) %></title>
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
6
+ <meta name="viewport" content="width=device-width">
7
+ <meta name="apple-mobile-web-app-title" content="<% application_name %>">
8
+
9
+ <%= render '/layouts/lentil/apple_touch_icons' %>
10
+
11
+ <%= meta_description_tag %>
12
+ <%= stylesheet_link_tag "lentil/iframe", :media => "all" %>
13
+ <%= javascript_include_tag "lentil/iframe" %>
14
+ <%= yield :javascript_includes %>
15
+
16
+ <%= analytics_init(:tracker => google_analytics_tracker()) if (Rails.env.production? && !google_analytics_tracker.nil?) %>
17
+ <% if content_for? :feed_auto_discovery %>
18
+ <%= yield :feed_auto_discovery %>
19
+ <% end -%>
20
+
21
+ <%= csrf_meta_tags %>
22
+ </head>
23
+ <!--[if IE 7]> <body class="lt-ie9 lt-ie8 <%= body_class %>"> <![endif]-->
24
+ <!--[if IE 8]> <body class="lt-ie9 <%= body_class %>"> <![endif]-->
25
+ <!--[if gt IE 8]><!--> <body class="<%= body_class %>"> <!--<![endif]-->
26
+
27
+ <%= yield %>
28
+
29
+ </body>
30
+ </html>
@@ -0,0 +1,9 @@
1
+ <%= link_to main_app.root_path, :target => "_parent" do %>
2
+ <div id="iframe-wrapper">
3
+ <% @images.each do |image| %>
4
+ <div class="iframe-tile">
5
+ <%= image_tag(image.thumbnail_url, :class => "instagram-img " + image.id.to_s, :alt => image.description) %>
6
+ </div>
7
+ <% end -%>
8
+ </div>
9
+ <% end %>
data/config/routes.rb CHANGED
@@ -8,6 +8,7 @@ Lentil::Engine.routes.draw do
8
8
  get "images/staff_picks" => 'images#staff_picks', :as => :images_staff_picks
9
9
  get "images/animate" => 'images#animate', :as => :images_animate
10
10
  get "images/staff_picks_animate" => 'images#staff_picks_animate', :as => :staff_picks_animate
11
+ get "images/iframe" => 'images#iframe', :as => :images_iframe
11
12
  get "about" => 'pages#about', :as => :pages_about
12
13
  post 'like_votes/:image_id' => 'like_votes#tally', :as => :tally_like_vote
13
14
  post 'flags/:image_id' => 'flags#tally', :as => :tally_flag
@@ -8,6 +8,21 @@ module Lentil
8
8
  remove_file('public/index.html')
9
9
  end
10
10
 
11
+ desc 'insert lentil config comments'
12
+ def lentil_config_comments
13
+ insert_into_file "config/application.rb", "\n # Inserted by lentil\n # End of lentil changes\n\n", :after => "class Application < Rails::Application\n"
14
+ end
15
+
16
+ desc 'precompile additional assets'
17
+ def precompile_assets
18
+ insert_into_file "config/application.rb", " config.assets.precompile += %w( lentil/iframe.js lentil/iframe.css )\n", :after => "# Inserted by lentil\n"
19
+ end
20
+
21
+ desc 'do not enforce available locales'
22
+ def set_enforce_available_locales
23
+ insert_into_file "config/application.rb", " I18n.enforce_available_locales = true\n", :after => "# Inserted by lentil\n"
24
+ end
25
+
11
26
  desc 'install migrations'
12
27
  def install_migrations
13
28
  rake "lentil:install:migrations"
@@ -20,9 +35,9 @@ module Lentil
20
35
  rake "db:seed"
21
36
  end
22
37
 
23
- desc 'create devise initializer'
24
- def create_devise_initializer
25
- copy_file 'devise.rb', 'config/initializers/devise.rb'
38
+ desc 'install_devise_files'
39
+ def install_devise_files
40
+ generate 'devise:install'
26
41
  end
27
42
 
28
43
  desc 'install active_admin'
@@ -8,6 +8,12 @@ You will need to make the following changes:
8
8
 
9
9
  2. You may need to configure config/initializers/devise.rb
10
10
 
11
+ 3. From the Devise documentation: "Ensure you have defined default url options in your environments files. Here is an example of default_url_options appropriate for a development environment in config/environments/development.rb:
12
+
13
+ config.action_mailer.default_url_options = { :host => 'localhost:3000' }
14
+
15
+ In production, :host should be set to the actual host of your application."
16
+
11
17
  3. Update that config/lentil_config.yml with your information. It is probably a good idea to add that file to your .gitignore too. You'll definitely want to change your instagram values and the default_image_search_tag.
12
18
 
13
19
  4. Look at the README.md for how to begin harvesting images and customizing your application.
@@ -197,7 +197,7 @@ module Lentil
197
197
  #
198
198
  # @return [String] Binary image data
199
199
  def harvest_image_data(image)
200
- response = Typhoeus.get(image.image_url, followlocation: true)
200
+ response = Typhoeus.get(image.large_url, followlocation: true)
201
201
 
202
202
  if response.success?
203
203
  raise "Invalid content type: " + response.headers['Content-Type'] unless (response.headers['Content-Type'] == 'image/jpeg')
@@ -221,7 +221,7 @@ module Lentil
221
221
  #
222
222
  # @return [Boolean] Whether the image request was successful
223
223
  def test_remote_image(image)
224
- response = Typhoeus.head(image.image_url, followlocation: true)
224
+ response = Typhoeus.get(image.thumbnail_url, followlocation: true)
225
225
 
226
226
  if response.success?
227
227
  true
@@ -1,3 +1,3 @@
1
1
  module Lentil
2
- VERSION = "0.1.7"
2
+ VERSION = "0.1.8"
3
3
  end
@@ -7,6 +7,12 @@ require "lentil"
7
7
 
8
8
  module Dummy
9
9
  class Application < Rails::Application
10
+
11
+ # Inserted by lentil
12
+ I18n.enforce_available_locales = true
13
+ config.assets.precompile += %w( lentil/iframe.js lentil/iframe.css )
14
+ # End of lentil changes
15
+
10
16
  # Settings in config/environments/* take precedence over those specified here.
11
17
  # Application configuration should go into files in config/initializers
12
18
  # -- all .rb files in that directory are automatically loaded.