oh dang, did we just fix most of the mixed content?

This commit is contained in:
Matchu 2015-08-05 20:11:08 -04:00
parent 4a18f22571
commit b11d7a8c9c
10 changed files with 265 additions and 304 deletions

View file

@ -225,11 +225,13 @@ var Neopia = (function($, I18n) {
Neopia.init(); Neopia.init();
this._createItems($); this._createItems($);
var usersEl = $('#modeling-neopets-users'); var usersEl = $('#modeling-neopets-users');
this._usersComponent = React.renderComponent(<NeopetsUsernamesForm />, if (usersEl.length) {
usersEl.get(0)); this._usersComponent = React.renderComponent(<NeopetsUsernamesForm />,
var usernames = ImpressUser.getNeopetsUsernames(); usersEl.get(0));
usernames.forEach(this._registerUsername.bind(this)); var usernames = ImpressUser.getNeopetsUsernames();
this._updateUsernames(); usernames.forEach(this._registerUsername.bind(this));
this._updateUsernames();
}
}, },
model: function(neopiaPetId, itemId) { model: function(neopiaPetId, itemId) {
var oldCustomization = this._customizationsByPetId[neopiaPetId]; var oldCustomization = this._customizationsByPetId[neopiaPetId];

View file

@ -1,315 +1,252 @@
var disqus_shortname = 'dresstoimpress';
(function () { // don't need to export anything in here (function () { // don't need to export anything in here
var preview_el = $('#pet-preview'), var preview_el = $('#pet-preview'),
img_el = preview_el.find('img'), img_el = preview_el.find('img'),
response_el = preview_el.find('span'); response_el = preview_el.find('span');
var defaultPreviewUrl = img_el.attr('src'); var defaultPreviewUrl = img_el.attr('src');
preview_el.click(function () { preview_el.click(function () {
Preview.Job.current.visit(); Preview.Job.current.visit();
}); });
var Preview = { var Preview = {
clear: function () { clear: function () {
if(typeof Preview.Job.fallback != 'undefined') Preview.Job.fallback.setAsCurrent(); if(typeof Preview.Job.fallback != 'undefined') Preview.Job.fallback.setAsCurrent();
}, },
displayLoading: function () { displayLoading: function () {
preview_el.addClass('loading'); preview_el.addClass('loading');
response_el.text('Loading...'); response_el.text('Loading...');
}, },
failed: function () { failed: function () {
preview_el.addClass('hidden'); preview_el.addClass('hidden');
}, },
notFound: function (key, options) { notFound: function (key, options) {
Preview.failed(); Preview.failed();
response_el.empty(); response_el.empty();
$('#preview-' + key + '-template').tmpl(options).appendTo(response_el); $('#preview-' + key + '-template').tmpl(options).appendTo(response_el);
}, },
updateWithName: function (name_el) { updateWithName: function (name_el) {
var name = name_el.val(), job; var name = name_el.val(), job;
if(name) { if(name) {
currentName = name; currentName = name;
if(!Preview.Job.current || name != Preview.Job.current.name) { if(!Preview.Job.current || name != Preview.Job.current.name) {
job = new Preview.Job.Name(name); job = new Preview.Job.Name(name);
job.setAsCurrent(); job.setAsCurrent();
Preview.displayLoading(); Preview.displayLoading();
}
} else {
Preview.clear();
} }
} else {
Preview.clear();
} }
} }
}
function loadNotable() { function loadNotable() {
$.getJSON('http://notables.openneo.net/api/1/days/ago/1?callback=?', function (response) { // TODO: add HTTPS to notables
var notables = response.notables; // $.getJSON('http://notables.openneo.net/api/1/days/ago/1?callback=?', function (response) {
var i = Math.floor(Math.random() * notables.length); // var notables = response.notables;
Preview.Job.fallback = new Preview.Job.Name(notables[i].petName); // var i = Math.floor(Math.random() * notables.length);
// Preview.Job.fallback = new Preview.Job.Name(notables[i].petName);
// if(!Preview.Job.current) {
// Preview.Job.fallback.setAsCurrent();
// }
// });
if(!Preview.Job.current) { if(!Preview.Job.current) {
Preview.Job.fallback.setAsCurrent(); Preview.Job.fallback.setAsCurrent();
} }
}); }
}
function loadFeature() { function loadFeature() {
$.getJSON('/donations/features', function(features) { $.getJSON('/donations/features', function(features) {
if (features.length > 0) { if (features.length > 0) {
var feature = features[Math.floor(Math.random() * features.length)]; var feature = features[Math.floor(Math.random() * features.length)];
Preview.Job.fallback = new Preview.Job.Feature(feature); Preview.Job.fallback = new Preview.Job.Feature(feature);
if (!Preview.Job.current) { if (!Preview.Job.current) {
Preview.Job.fallback.setAsCurrent(); Preview.Job.fallback.setAsCurrent();
}
} else {
loadNotable();
} }
} else { });
loadNotable();
}
});
}
loadFeature();
Preview.Job = function (key, base) {
var job = this,
quality = 2;
job.loading = false;
function getImageSrc() {
if (key.substr(0, 3) === 'a:-') {
// lol lazy code for prank image :P
return "http://swfimages.impress.openneo.net" +
"/biology/000/000/0-2/" + key.substr(2) + "/300x300.png";
} else if (base === 'cp' || base === 'cpn') {
return petImage(base + '/' + key, quality);
} else if (base === 'url') {
return key;
} else {
throw new Error("unrecognized image base " + base);
}
} }
function load() { loadFeature();
job.loading = true;
img_el.attr('src', getImageSrc());
}
this.increaseQualityIfPossible = function () { Preview.Job = function (key, base) {
if(quality == 2) { var job = this,
quality = 4; quality = 2;
job.loading = false;
function getImageSrc() {
if (key.substr(0, 3) === 'a:-') {
// lol lazy code for prank image :P
// TODO: HTTPS?
return "http://swfimages.impress.openneo.net" +
"/biology/000/000/0-2/" + key.substr(2) + "/300x300.png";
} else if (base === 'cp' || base === 'cpn') {
return petImage(base + '/' + key, quality);
} else if (base === 'url') {
return key;
} else {
throw new Error("unrecognized image base " + base);
}
}
function load() {
job.loading = true;
img_el.attr('src', getImageSrc());
}
this.increaseQualityIfPossible = function () {
if(quality == 2) {
quality = 4;
load();
}
}
this.setAsCurrent = function () {
Preview.Job.current = job;
load(); load();
} }
this.notFound = function() {
Preview.notFound('pet-not-found');
}
} }
this.setAsCurrent = function () { Preview.Job.Name = function (name) {
Preview.Job.current = job; this.name = name;
load(); Preview.Job.apply(this, [name, 'cpn']);
this.visit = function() {
$('.main-pet-name').val(this.name).closest('form').submit();
}
} }
this.notFound = function() { Preview.Job.Hash = function (hash, form) {
Preview.notFound('pet-not-found'); Preview.Job.apply(this, [hash, 'cp']);
}
}
Preview.Job.Name = function (name) { this.visit = function() {
this.name = name; window.location = "/wardrobe?color=" + form.find('.color').val() + "&species=" +
Preview.Job.apply(this, [name, 'cpn']); form.find('.species').val();
}
this.visit = function() {
$('.main-pet-name').val(this.name).closest('form').submit();
}
}
Preview.Job.Hash = function (hash, form) {
Preview.Job.apply(this, [hash, 'cp']);
this.visit = function() {
window.location = "/wardrobe?color=" + form.find('.color').val() + "&species=" +
form.find('.species').val();
}
}
Preview.Job.Feature = function(feature) {
Preview.Job.apply(this, [feature.outfit_image_url, 'url']);
this.name = "Thanks for donating, " + feature.donor_name + "!"; // TODO: i18n
this.visit = function() {
window.location = '/donate';
} }
this.notFound = function() { Preview.Job.Feature = function(feature) {
// The outfit thumbnail hasn't generated or is missing or something. Preview.Job.apply(this, [feature.outfit_image_url, 'url']);
// Let's fall back to a boring image for now. this.name = "Thanks for donating, " + feature.donor_name + "!"; // TODO: i18n
var boring = new Preview.Job.Feature({
donor_name: feature.donor_name, this.visit = function() {
outfit_image_url: defaultPreviewUrl window.location = '/donate';
}
this.notFound = function() {
// The outfit thumbnail hasn't generated or is missing or something.
// Let's fall back to a boring image for now.
var boring = new Preview.Job.Feature({
donor_name: feature.donor_name,
outfit_image_url: defaultPreviewUrl
});
boring.setAsCurrent();
}
}
$(function () {
var previewWithNameTimeout;
var name_el = $('.main-pet-name');
name_el.val(PetQuery.name);
Preview.updateWithName(name_el);
name_el.keyup(function () {
if(previewWithNameTimeout) {
clearTimeout(previewWithNameTimeout);
Preview.Job.current.loading = false;
}
var name_el = $(this);
previewWithNameTimeout = setTimeout(function() {
Preview.updateWithName(name_el);
}, 250);
}); });
boring.setAsCurrent();
}
}
img_el.load(function () {
$(function () { if(Preview.Job.current.loading) {
var previewWithNameTimeout; Preview.Job.loading = false;
Preview.Job.current.increaseQualityIfPossible();
var name_el = $('.main-pet-name'); preview_el.removeClass('loading').removeClass('hidden').addClass('loaded');
name_el.val(PetQuery.name); response_el.text(Preview.Job.current.name);
Preview.updateWithName(name_el); }
}).error(function () {
name_el.keyup(function () { if(Preview.Job.current.loading) {
if(previewWithNameTimeout) { Preview.Job.loading = false;
clearTimeout(previewWithNameTimeout); Preview.Job.current.notFound();
Preview.Job.current.loading = false; }
}
var name_el = $(this);
previewWithNameTimeout = setTimeout(function() {
Preview.updateWithName(name_el);
}, 250);
});
img_el.load(function () {
if(Preview.Job.current.loading) {
Preview.Job.loading = false;
Preview.Job.current.increaseQualityIfPossible();
preview_el.removeClass('loading').removeClass('hidden').addClass('loaded');
response_el.text(Preview.Job.current.name);
}
}).error(function () {
if(Preview.Job.current.loading) {
Preview.Job.loading = false;
Preview.Job.current.notFound();
}
});
$('.species, .color').change(function () {
var type = {}, nameComponents = {};
var form = $(this).closest('form');
form.find('select').each(function () {
var el = $(this), selectedEl = el.children(':selected'), key = el.attr('name');
type[key] = selectedEl.val();
nameComponents[key] = selectedEl.text();
}); });
name = nameComponents.color + ' ' + nameComponents.species;
Preview.displayLoading(); $('.species, .color').change(function () {
$.ajax({ var type = {}, nameComponents = {};
url: '/species/' + type.species + '/color/' + type.color + '/pet_type.json', var form = $(this).closest('form');
data: { form.find('select').each(function () {
'for': 'image' var el = $(this), selectedEl = el.children(':selected'), key = el.attr('name');
}, type[key] = selectedEl.val();
dataType: 'json', nameComponents[key] = selectedEl.text();
success: function (data) { });
var job; name = nameComponents.color + ' ' + nameComponents.species;
if(data) { Preview.displayLoading();
job = new Preview.Job.Hash(data.image_hash, form); $.ajax({
job.name = name; url: '/species/' + type.species + '/color/' + type.color + '/pet_type.json',
job.setAsCurrent(); data: {
} else { 'for': 'image'
Preview.notFound('pet-type-not-found', { },
color_name: nameComponents.color, dataType: 'json',
species_name: nameComponents.species success: function (data) {
}); var job;
if(data) {
job = new Preview.Job.Hash(data.image_hash, form);
job.name = name;
job.setAsCurrent();
} else {
Preview.notFound('pet-type-not-found', {
color_name: nameComponents.color,
species_name: nameComponents.species
});
}
} }
});
});
var neopiaError = document.location.search.match(/neopia%5Berror%5D=([^&]+)/);
if (neopiaError !== null) {
var message = decodeURI(neopiaError[1]).replace(/\+/g, ' ');
if (message === "pet not found") {
$('#pet-not-found').show();
} else {
var el = $('#neopia-error');
var text = el.text().replace('%{message}', message);
el.text(text).show();
} }
}
$('.load-pet-to-wardrobe').submit(function(e) {
if ($(this).find('.main-pet-name').val() === "" && Preview.Job.current) {
e.preventDefault();
Preview.Job.current.visit();
}
});
function setNeopiaStatus(isOnline) {
$('#outfit-forms').attr('data-neopia-status', isOnline ? 'online' : 'offline');
}
Neopia.Status.get().then(function(r) {
setNeopiaStatus(!!r.status);
}).fail(function() {
setNeopiaStatus(false);
}); });
}); });
$.getJSON('http://blog.openneo.net/api/read/json?callback=?', function (data) { $('#latest-contribution-created-at').timeago();
var post = data.posts[0], el = $('#blog-preview'),
url = post['url-with-slug'], header = "Here's the latest!", body = '',
truncate_body_at = 500, image;
if(post.type == 'regular') {
header = post['regular-title'];
body = post['regular-body'];
} else if(post.type == 'link') {
header = post['link-text'];
body = post['link-description'];
} else if(post.type == 'photo') {
body = post['photo-caption'];
image = post['photo-url-75'];
}
// No truncation on this new layout
/*body = body.replace(/(<\/?[\S][^>]*>)/gi, '');
if(body.length > truncate_body_at) {
body = body.substring(0, truncate_body_at);
body = body.replace(/\s+\w+$/, '');
body += '&hellip;';
}*/
el.find('h2').text(header).wrapInner($('<a/>', {href: url}));
var contentEl = el.find('div');
contentEl.html(body);
$('<a/>', {'id': 'blog-preview-comments', href: url + '#disqus_thread'}).appendTo(el);
if(image) {
el.find('img').attr('src', image).parent().attr('href', url);
}
// Localize
var localizedBodies = {};
contentEl.find('.locale').each(function () {
var localizedBody = $(this);
var locale = localizedBody.attr('class').match(/locale-(\S+)/)[1];
localizedBodies[locale] = localizedBody;
});
var fallbacks = $('#locale option:selected').attr('data-fallbacks').split(',');
var bestLocale = null;
for(var i = 0; i < fallbacks.length; i++) {
if(localizedBodies.hasOwnProperty(fallbacks[i])) {
bestLocale = fallbacks[i];
break;
}
}
if(bestLocale) {
// I feel bad doing all this in JS rather than CSS, but sometimes you
// gotta do what you gotta do if you wanna support any number of locales.
for(var locale in localizedBodies) {
localizedBodies[locale].hide();
}
localizedBodies[bestLocale].show();
contentEl.find('.no-locale').hide();
}
el.fadeIn('medium');
addDisqusCount();
});
var neopiaError = document.location.search.match(/neopia%5Berror%5D=([^&]+)/);
if (neopiaError !== null) {
var message = decodeURI(neopiaError[1]).replace(/\+/g, ' ');
if (message === "pet not found") {
$('#pet-not-found').show();
} else {
var el = $('#neopia-error');
var text = el.text().replace('%{message}', message);
el.text(text).show();
}
}
$('.load-pet-to-wardrobe').submit(function(e) {
if ($(this).find('.main-pet-name').val() === "" && Preview.Job.current) {
e.preventDefault();
Preview.Job.current.visit();
}
});
function setNeopiaStatus(isOnline) {
$('#outfit-forms').attr('data-neopia-status', isOnline ? 'online' : 'offline');
}
Neopia.Status.get().then(function(r) {
setNeopiaStatus(!!r.status);
}).fail(function() {
setNeopiaStatus(false);
});
});
function addDisqusCount() {
var s = document.createElement('script'); s.async = true;
s.type = 'text/javascript';
s.src = 'http://' + disqus_shortname + '.disqus.com/count.js';
(document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);}
})(); })();
$('#latest-contribution-created-at').timeago();

View file

@ -216,17 +216,7 @@ module ApplicationHelper
end end
def camo_image_url(image_url) def camo_image_url(image_url)
if CAMO_KEY Image.from_insecure_url(image_url).secure_url
hexdigest = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), CAMO_KEY, image_url)
uri = Addressable::URI.parse("#{CAMO_HOST}/#{hexdigest}")
uri.query_values = { 'url' => image_url, 'repo' => '', 'path' => '' }
uri.to_s
else
uri = Addressable::URI.parse(image_url)
query_values = uri.query_values || {}
uri.query_values = query_values.merge(NO_CAMO_CONFIG: nil)
uri.to_s
end
end end
end end

View file

@ -19,7 +19,7 @@ module ContributionHelper
:item_link => link) :item_link => link)
output = translate("contributions.contributed_description.main.#{main_key}_html", output = translate("contributions.contributed_description.main.#{main_key}_html",
:item_description => description) :item_description => description)
output << image_tag(item.thumbnail_url) if show_image output << image_tag(item.thumbnail.secure_url) if show_image
output output
else else
translate('contributions.contributed_description.parents.item.blank') translate('contributions.contributed_description.parents.item.blank')

28
app/models/image.rb Normal file
View file

@ -0,0 +1,28 @@
class Image
attr_reader :insecure_url, :secure_url
def initialize(insecure_url, secure_url)
@insecure_url = insecure_url
@secure_url = secure_url
end
def self.from_insecure_url(insecure_url)
Image.new insecure_url, proxy_insecure_url(insecure_url)
end
private
def self.proxy_insecure_url(insecure_url)
if CAMO_HOST && CAMO_KEY
hexdigest = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), CAMO_KEY, insecure_url)
uri = Addressable::URI.parse("#{CAMO_HOST}/#{hexdigest}")
uri.query_values = { url: insecure_url }
uri.to_s
else
uri = Addressable::URI.parse(insecure_url)
query_values = uri.query_values || {}
uri.query_values = query_values.merge(NO_CAMO_CONFIG: nil)
uri.to_s
end
end
end

View file

@ -327,12 +327,16 @@ class Item < ActiveRecord::Base
modeled_body_ids.size.to_f / predicted_body_ids.size modeled_body_ids.size.to_f / predicted_body_ids.size
end end
def thumbnail
@thumbnail ||= Image.from_insecure_url(thumbnail_url)
end
def as_json(options={}) def as_json(options={})
json = { json = {
:description => description, :description => description,
:id => id, :id => id,
:name => name, :name => name,
:thumbnail_url => thumbnail_url, :thumbnail_url => thumbnail.secure_url,
:zones_restrict => zones_restrict, :zones_restrict => zones_restrict,
:rarity_index => rarity_index, :rarity_index => rarity_index,
:nc => nc? :nc => nc?

View file

@ -5,7 +5,7 @@ class Item
attr_reader :id attr_reader :id
attr_writer :item, :owned, :wanted attr_writer :item, :owned, :wanted
delegate :description, :name, :nc?, :thumbnail_url, :to_param, to: :item delegate :description, :name, :nc?, :thumbnail_url, :thumbnail, :to_param, to: :item
def self.model_name def self.model_name
Item.model_name Item.model_name

View file

@ -1,4 +1,4 @@
= link_to item_path(item) do = link_to item_path(item) do
= image_tag item.thumbnail_url, :alt => item.description, :title => item.description = image_tag item.thumbnail.secure_url, :alt => item.description, :title => item.description
%span.name= item.name %span.name= item.name
= nc_icon_for(item) = nc_icon_for(item)

View file

@ -3,7 +3,7 @@
- localized_cache "items/#{@item.id} header" do - localized_cache "items/#{@item.id} header" do
%header#item-header %header#item-header
= image_tag @item.thumbnail_url, :id => 'item-thumbnail' = image_tag @item.thumbnail.secure_url, :id => 'item-thumbnail'
%div %div
%h2#item-name= @item.name %h2#item-name= @item.name
= nc_icon_for(@item) = nc_icon_for(@item)

View file

@ -80,7 +80,7 @@
%li %li
= link_to bulk_pets_path do = link_to bulk_pets_path do
= image_tag 'http://images.neopets.com/items/mall_ac_garland_spotlight.gif' = image_tag camo_image_url('http://images.neopets.com/items/mall_ac_garland_spotlight.gif')
%h3= link_to t('modeling_hub'), bulk_pets_path %h3= link_to t('modeling_hub'), bulk_pets_path
%div %div
%h4= t '.modeling_hub.tagline' %h4= t '.modeling_hub.tagline'
@ -108,7 +108,7 @@
- @newest_unmodeled_items.each do |item| - @newest_unmodeled_items.each do |item|
- localized_cache "items/#{item.id} modeling_progress updated_at=#{item.updated_at.to_i}" do - localized_cache "items/#{item.id} modeling_progress updated_at=#{item.updated_at.to_i}" do
%li{'data-item-id' => item.id} %li{'data-item-id' => item.id}
= link_to image_tag(item.thumbnail_url), item, :class => 'image-link' = link_to image_tag(item.thumbnail.secure_url), item, :class => 'image-link'
= link_to item, :class => 'header' do = link_to item, :class => 'header' do
%h2= item.name %h2= item.name
%span.meter{style: "width: #{@newest_unmodeled_items_predicted_modeled_ratio[item]*100}%"} %span.meter{style: "width: #{@newest_unmodeled_items_predicted_modeled_ratio[item]*100}%"}
@ -121,7 +121,7 @@
- @newest_modeled_items.each do |item| - @newest_modeled_items.each do |item|
%li.object %li.object
= link_to item, title: item.name, alt: item.name do = link_to item, title: item.name, alt: item.name do
= image_tag item.thumbnail_url = image_tag item.thumbnail.secure_url
= nc_icon_for(item) = nc_icon_for(item)