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.
- checksums.yaml +4 -4
- data/README.md +10 -0
- data/app/assets/javascripts/lentil/addfancybox.js +3 -1
- data/app/assets/javascripts/lentil/iframe.js +117 -0
- data/app/assets/javascripts/lentil/thisorthat.js.erb +18 -20
- data/app/assets/stylesheets/lentil/iframe.css.scss +26 -0
- data/app/controllers/lentil/images_controller.rb +4 -0
- data/app/controllers/lentil/thisorthat_controller.rb +6 -4
- data/app/models/lentil/image.rb +16 -6
- data/app/views/layouts/lentil/iframe.html.erb +30 -0
- data/app/views/lentil/images/iframe.html.erb +9 -0
- data/config/routes.rb +1 -0
- data/lib/generators/lentil/install_generator.rb +18 -3
- data/lib/generators/lentil/templates/README.md +6 -0
- data/lib/lentil/instagram_harvester.rb +2 -2
- data/lib/lentil/version.rb +1 -1
- data/test/dummy/config/application.rb +6 -0
- data/test/fixtures/lentil/images.yml +84 -84
- data/test/functional/lentil/images_controller_test.rb +5 -0
- data/test/functional/lentil/photographers_controller_test.rb +1 -1
- data/test/integration/lentil/images_index_test.rb +2 -3
- data/test/integration/lentil/javascript/event_tracking_battle_test.rb +1 -2
- data/test/integration/lentil/javascript/image_modal_test.rb +2 -2
- data/test/vcr_cassettes/battle_images.yml +190 -135
- data/test/vcr_cassettes/battle_images_events.yml +123 -167
- data/test/vcr_cassettes/instagram_bad_image_check.yml +24 -21
- data/test/vcr_cassettes/instagram_good_image_check.yml +160 -15
- data/test/vcr_cassettes/instagram_image_harvest.yml +1990 -1950
- data/test/vcr_cassettes/instagram_oembed.yml +18 -9
- data/vendor/assets/javascripts/imagesloaded/jquery.imagesloaded.min.js +888 -3
- metadata +15 -12
- data/lib/generators/lentil/templates/devise.rb +0 -232
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6eb56f9468aa49f44f97b76acb8713076fd16845
|
4
|
+
data.tar.gz: 9d8b405b398bbe5cb2158ff23413458e3fd8c140
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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(
|
24
|
-
|
25
|
-
|
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
|
-
|
67
|
-
|
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
|
+
}
|
@@ -6,10 +6,12 @@ module Lentil
|
|
6
6
|
|
7
7
|
def test_urls(images, quantity)
|
8
8
|
image = images.selecting{ |i|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
|
data/app/models/lentil/image.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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 '
|
24
|
-
def
|
25
|
-
|
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.
|
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.
|
224
|
+
response = Typhoeus.get(image.thumbnail_url, followlocation: true)
|
225
225
|
|
226
226
|
if response.success?
|
227
227
|
true
|
data/lib/lentil/version.rb
CHANGED
@@ -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.
|