From 504cfcff9644b53f0bc51a4fb890558d270cba9f Mon Sep 17 00:00:00 2001 From: Sam Date: Mon, 26 May 2014 19:46:43 +1000 Subject: [PATCH] Fix specs for avatars Implement avatar picker Correct avatar related jobs --- .../controllers/avatar-selector.js.es6 | 27 +++++++++++++ .../discourse/helpers/application_helpers.js | 22 ++++++++--- .../javascripts/discourse/models/user.js | 15 +++----- .../discourse/routes/preferences_routes.js | 38 +++++++++++++------ .../discourse/templates/header.js.handlebars | 2 +- .../modal/avatar_selector.js.handlebars | 16 +++++--- .../templates/modal/history.js.handlebars | 4 +- .../templates/poster_expansion.handlebars | 2 +- .../templates/user/preferences.js.handlebars | 2 +- .../templates/user/user.js.handlebars | 2 +- .../views/modal/avatar_selector_view.js | 22 +++++------ ...ntroller.rb => user_avatars_controller.rb} | 26 ++++++++++--- app/controllers/users_controller.rb | 17 ++++++--- app/jobs/regular/create_missing_avatars.rb | 10 ----- app/jobs/scheduled/clean_up_uploads.rb | 9 +++-- app/jobs/scheduled/create_missing_avatars.rb | 15 ++++++++ app/models/user.rb | 19 +++++----- app/models/user_avatar.rb | 11 ++++-- app/serializers/user_action_serializer.rb | 13 ------- config/routes.rb | 8 ++-- db/fixtures/005_users.rb | 5 --- db/migrate/20140522003151_add_user_avatars.rb | 14 ++++++- ...ove_uploaded_avatar_template_from_users.rb | 5 +++ spec/components/cooked_post_processor_spec.rb | 3 +- spec/controllers/users_controller_spec.rb | 33 +++++----------- spec/models/optimized_image_spec.rb | 16 ++++---- spec/models/user_spec.rb | 30 +++++++-------- 27 files changed, 228 insertions(+), 158 deletions(-) rename app/controllers/{avatar_controller.rb => user_avatars_controller.rb} (63%) delete mode 100644 app/jobs/regular/create_missing_avatars.rb create mode 100644 app/jobs/scheduled/create_missing_avatars.rb create mode 100644 db/migrate/20140525233953_remove_uploaded_avatar_template_from_users.rb diff --git a/app/assets/javascripts/discourse/controllers/avatar-selector.js.es6 b/app/assets/javascripts/discourse/controllers/avatar-selector.js.es6 index af6642bc7..76e2c766f 100644 --- a/app/assets/javascripts/discourse/controllers/avatar-selector.js.es6 +++ b/app/assets/javascripts/discourse/controllers/avatar-selector.js.es6 @@ -9,6 +9,23 @@ **/ export default Discourse.Controller.extend(Discourse.ModalFunctionality, { + selectedUploadId: function(){ + switch(this.get("selected")){ + case "system": + return this.get("system_avatar_upload_id"); + break; + case "gravatar": + return this.get("gravatar_avatar_upload_id"); + break; + default: + return this.get("custom_avatar_upload_id"); + } + }.property( + 'selected', + 'system_avatar_upload_id', + 'gravatar_avatar_upload_id', + 'custom_avatar_upload_id'), + actions: { useUploadedAvatar: function() { this.set("selected", "uploaded"); @@ -18,6 +35,16 @@ export default Discourse.Controller.extend(Discourse.ModalFunctionality, { }, useSystem: function() { this.set("selected", "system"); + }, + refreshGravatar: function(){ + var self = this; + self.set("gravatarRefreshDisabled", true); + Discourse + .ajax("/user_avatar/" + this.get("username") + "/refresh_gravatar", {method: 'POST'}) + .then(function(result){ + self.set("gravatarRefreshDisabled", false); + self.set("gravatar_avatar_upload_id", result.upload_id); + }); } } }); diff --git a/app/assets/javascripts/discourse/helpers/application_helpers.js b/app/assets/javascripts/discourse/helpers/application_helpers.js index 6b3bacaf7..f97669ee5 100644 --- a/app/assets/javascripts/discourse/helpers/application_helpers.js +++ b/app/assets/javascripts/discourse/helpers/application_helpers.js @@ -216,25 +216,35 @@ Handlebars.registerHelper('avatar', function(user, options) { /** Bound avatar helper. - Will rerender whenever the "avatar_template" changes. @method boundAvatar @for Handlebars **/ -Ember.Handlebars.registerBoundHelper('boundAvatar', function(user, options) { +Ember.Handlebars.registerBoundHelper('boundAvatar', function(user, size, uploadId) { var username = Em.get(user, 'username'); - console.log(options.hash); + if(arguments.length < 4){ + uploadId = Em.get(user, 'uploaded_avatar_id'); + } - var uploadId = (options.hash.uploadId && Em.get(user, options.hash.uploadId)) || Em.get(user, 'uploaded_avatar_id'); var avatarTemplate = Discourse.User.avatarTemplate(username,uploadId); return new Handlebars.SafeString(Discourse.Utilities.avatarImg({ - size: options.hash.imageSize, + size: size, avatarTemplate: avatarTemplate })); -}, 'uploadId', 'username', 'uploaded_avatar_id'); +}, 'uploaded_avatar_id'); + +/* + * Used when we only have a template + */ +Ember.Handlebars.registerBoundHelper('boundAvatarTemplate', function(avatarTemplate, size) { + return new Handlebars.SafeString(Discourse.Utilities.avatarImg({ + size: size, + avatarTemplate: avatarTemplate + })); +}); /** Nicely format a date without binding or returning HTML diff --git a/app/assets/javascripts/discourse/models/user.js b/app/assets/javascripts/discourse/models/user.js index 5e1138cc1..d1d317bec 100644 --- a/app/assets/javascripts/discourse/models/user.js +++ b/app/assets/javascripts/discourse/models/user.js @@ -332,15 +332,12 @@ Discourse.User = Discourse.Model.extend({ /* Change avatar selection - - @method toggleAvatarSelection - @param {Boolean} useUploadedAvatar true if the user is using the uploaded avatar - @returns {Promise} the result of the toggle avatar selection */ - toggleAvatarSelection: function(useUploadedAvatar) { - return Discourse.ajax("/users/" + this.get("username_lower") + "/preferences/avatar/toggle", { + pickAvatar: function(uploadId) { + this.set("uploaded_avatar_id", uploadId); + return Discourse.ajax("/users/" + this.get("username_lower") + "/preferences/avatar/pick", { type: 'PUT', - data: { use_uploaded_avatar: useUploadedAvatar } + data: { upload_id: uploadId } }); }, @@ -403,7 +400,7 @@ Discourse.User = Discourse.Model.extend({ return this.get('can_delete_account') && ((this.get('reply_count')||0) + (this.get('topic_count')||0)) <= 1; }.property('can_delete_account', 'reply_count', 'topic_count'), - delete: function() { + "delete": function() { if (this.get('can_delete_account')) { return Discourse.ajax("/users/" + this.get('username'), { type: 'DELETE', @@ -419,7 +416,7 @@ Discourse.User = Discourse.Model.extend({ Discourse.User.reopenClass(Discourse.Singleton, { avatarTemplate: function(username, uploadedAvatarId){ - return Discourse.getURL("/avatar/" + username.toLowerCase() + "/{size}/" + uploadedAvatarId + ".png"); + return Discourse.getURL("/user_avatar/" + username.toLowerCase() + "/{size}/" + uploadedAvatarId + ".png"); }, /** diff --git a/app/assets/javascripts/discourse/routes/preferences_routes.js b/app/assets/javascripts/discourse/routes/preferences_routes.js index 5108dbd87..2c68967e9 100644 --- a/app/assets/javascripts/discourse/routes/preferences_routes.js +++ b/app/assets/javascripts/discourse/routes/preferences_routes.js @@ -20,30 +20,46 @@ Discourse.PreferencesRoute = Discourse.RestrictedUserRoute.extend({ showAvatarSelector: function() { Discourse.Route.showModal(this, 'avatar-selector'); // all the properties needed for displaying the avatar selector modal - this.controllerFor('avatar-selector').setProperties(this.modelFor('user').getProperties( + var controller = this.controllerFor('avatar-selector'); + var user = this.modelFor('user'); + var props = user.getProperties( 'username', 'email', + 'uploaded_avatar_id', 'system_avatar_upload_id', - 'gravatr_avatar_upload_id', + 'gravatar_avatar_upload_id', 'custom_avatar_upload_id' - ) - ); + ); + + switch(props.uploaded_avatar_id){ + case props.system_avatar_upload_id: + props.selected = "system"; + break; + case props.gravatar_avatar_upload_id: + props.selected = "gravatar"; + break; + default: + props.selected = "uploaded"; + } + + controller.setProperties(props); }, saveAvatarSelection: function() { var user = this.modelFor('user'); var avatarSelector = this.controllerFor('avatar-selector'); + + // sends the information to the server if it has changed - if (avatarSelector.get('use_uploaded_avatar') !== user.get('use_uploaded_avatar')) { - user.toggleAvatarSelection(avatarSelector.get('use_uploaded_avatar')); + if (avatarSelector.get('selectedUploadId') !== user.get('uploaded_avatar_id')) { + user.pickAvatar(avatarSelector.get('selectedUploadId')); } + // saves the data back user.setProperties(avatarSelector.getProperties( - 'has_uploaded_avatar', - 'use_uploaded_avatar', - 'gravatar_template', - 'uploaded_avatar_template' + 'system_avatar_upload_id', + 'gravatar_avatar_upload_id', + 'custom_avatar_upload_id' )); - user.set('avatar_template', avatarSelector.get('avatarTemplate')); avatarSelector.send('closeModal'); }, diff --git a/app/assets/javascripts/discourse/templates/header.js.handlebars b/app/assets/javascripts/discourse/templates/header.js.handlebars index 03a8b76a1..111fbfae2 100644 --- a/app/assets/javascripts/discourse/templates/header.js.handlebars +++ b/app/assets/javascripts/discourse/templates/header.js.handlebars @@ -104,7 +104,7 @@ href="#" title='{{i18n user.avatar.title}}' id="current-user"> - {{boundAvatar currentUser imageSize="medium"}} + {{boundAvatar currentUser "medium"}} {{/if}} diff --git a/app/assets/javascripts/discourse/templates/modal/avatar_selector.js.handlebars b/app/assets/javascripts/discourse/templates/modal/avatar_selector.js.handlebars index a70d12d48..c5295b90f 100644 --- a/app/assets/javascripts/discourse/templates/modal/avatar_selector.js.handlebars +++ b/app/assets/javascripts/discourse/templates/modal/avatar_selector.js.handlebars @@ -2,18 +2,22 @@
- +
- - + +
- +
- {{i18n post.revisions.details.edited_by}} {{boundAvatar content imageSize="small"}} {{username}} {{date created_at}} {{#if edit_reason}} — {{edit_reason}}{{/if}} + {{i18n post.revisions.details.edited_by}} {{boundAvatar content "small"}} {{username}} {{date created_at}} {{#if edit_reason}} — {{edit_reason}}{{/if}}
{{#if title_changes}} @@ -32,7 +32,7 @@ {{/if}} {{#if user_changes}}
- {{boundAvatar user_changes.previous imageSize="small"}} {{user_changes.previous.username}} → {{boundAvatar user_changes.current imageSize="small"}} {{user_changes.current.username}} + {{boundAvatar user_changes.previous "small"}} {{user_changes.previous.username}} → {{boundAvatar user_changes.current imageSize="small"}} {{user_changes.current.username}}
{{/if}} {{#if wiki_changes}} diff --git a/app/assets/javascripts/discourse/templates/poster_expansion.handlebars b/app/assets/javascripts/discourse/templates/poster_expansion.handlebars index e521a4ece..65d733dcf 100644 --- a/app/assets/javascripts/discourse/templates/poster_expansion.handlebars +++ b/app/assets/javascripts/discourse/templates/poster_expansion.handlebars @@ -1,5 +1,5 @@ {{#if model}} - {{#link-to 'user' user}}{{boundAvatar model imageSize="huge"}}{{/link-to}} + {{#link-to 'user' user}}{{boundAvatar model "huge"}}{{/link-to}}

{{username}}

diff --git a/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars b/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars index 87d6f901a..1797eb99d 100644 --- a/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars +++ b/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars @@ -79,7 +79,7 @@
- {{boundAvatar model imageSize="large"}} + {{boundAvatar model "large"}} {{#if allowAvatarUpload}} {{else}} diff --git a/app/assets/javascripts/discourse/templates/user/user.js.handlebars b/app/assets/javascripts/discourse/templates/user/user.js.handlebars index b45b709ed..57553741e 100644 --- a/app/assets/javascripts/discourse/templates/user/user.js.handlebars +++ b/app/assets/javascripts/discourse/templates/user/user.js.handlebars @@ -64,7 +64,7 @@
- {{boundAvatar model imageSize="huge"}} + {{boundAvatar model "huge"}}

{{username}} {{{statusIcon}}}

diff --git a/app/assets/javascripts/discourse/views/modal/avatar_selector_view.js b/app/assets/javascripts/discourse/views/modal/avatar_selector_view.js index fb9ca8c45..01322d927 100644 --- a/app/assets/javascripts/discourse/views/modal/avatar_selector_view.js +++ b/app/assets/javascripts/discourse/views/modal/avatar_selector_view.js @@ -12,11 +12,12 @@ Discourse.AvatarSelectorView = Discourse.ModalBodyView.extend({ title: I18n.t('user.change_avatar.title'), uploading: false, uploadProgress: 0, - useGravatar: Em.computed.not("controller.use_uploaded_avatar"), - canSaveAvatarSelection: Em.computed.or("useGravatar", "controller.has_uploaded_avatar"), - saveDisabled: Em.computed.not("canSaveAvatarSelection"), + saveDisabled: false, + gravatarRefreshEnabled: Em.computed.not('controller.gravatarRefreshDisabled'), imageIsNotASquare : false, + hasUploadedAvatar: Em.computed.or('uploadedAvatarTemplate', 'controller.custom_avatar_upload_id'), + didInsertElement: function() { var self = this; var $upload = $("#avatar-input"); @@ -61,10 +62,8 @@ Discourse.AvatarSelectorView = Discourse.ModalBodyView.extend({ // make sure we have a url if (data.result.url) { // indicates the users is using an uploaded avatar - self.get("controller").setProperties({ - has_uploaded_avatar: true, - use_uploaded_avatar: true - }); + self.set("controller.custom_avatar_upload_id", data.result.upload_id); + // display a warning whenever the image is not a square self.set("imageIsNotASquare", data.result.width !== data.result.height); // in order to be as much responsive as possible, we're cheating a bit here @@ -72,7 +71,7 @@ Discourse.AvatarSelectorView = Discourse.ModalBodyView.extend({ // often, this file is not a square, so we need to crop it properly // this will also capture the first frame of animated avatars when they're not allowed Discourse.Utilities.cropAvatar(data.result.url, data.files[0].type).then(function(avatarTemplate) { - self.get("controller").set("uploaded_avatar_template", avatarTemplate); + self.set("uploadedAvatarTemplate", avatarTemplate); }); } else { bootbox.alert(I18n.t('post.errors.upload')); @@ -95,14 +94,15 @@ Discourse.AvatarSelectorView = Discourse.ModalBodyView.extend({ $("#avatar-input").fileupload("destroy"); }, - // *HACK* used to select the proper radio button + // *HACK* used to select the proper radio button, cause {{action}} + // stops the default behavior selectedChanged: function() { var self = this; Em.run.next(function() { - var value = self.get('controller.use_uploaded_avatar') ? 'uploaded_avatar' : 'gravatar'; + var value = self.get('controller.selected'); $('input:radio[name="avatar"]').val([value]); }); - }.observes('controller.use_uploaded_avatar'), + }.observes('controller.selected'), uploadButtonText: function() { return this.get("uploading") ? I18n.t("uploading") : I18n.t("user.change_avatar.upload_picture"); diff --git a/app/controllers/avatar_controller.rb b/app/controllers/user_avatars_controller.rb similarity index 63% rename from app/controllers/avatar_controller.rb rename to app/controllers/user_avatars_controller.rb index b996299eb..e60878afb 100644 --- a/app/controllers/avatar_controller.rb +++ b/app/controllers/user_avatars_controller.rb @@ -1,7 +1,23 @@ require_dependency 'letter_avatar' -class AvatarController < ApplicationController - skip_before_filter :check_xhr, :verify_authenticity_token +class UserAvatarsController < ApplicationController + skip_before_filter :check_xhr, :verify_authenticity_token, only: :show + + def refresh_gravatar + + user = User.find_by(username_lower: params[:username].downcase) + guardian.ensure_can_edit!(user) + + if user + user.create_user_avatar(user_id: user.id) unless user.user_avatar + user.user_avatar.update_gravatar! + + render json: {upload_id: user.user_avatar.gravatar_upload_id} + else + raise Discourse::NotFound + end + end + def show username = params[:username].to_s @@ -17,17 +33,17 @@ class AvatarController < ApplicationController raise Discourse::NotFound unless version > 0 && user_avatar = user.user_avatar - upload = version if user_avatar.contains_upload?(version) + upload = Upload.find(version) if user_avatar.contains_upload?(version) upload ||= user.uploaded_avatar if user.uploaded_avatar_id == version if user.uploaded_avatar && !upload return redirect_to "/avatar/#{user.username_lower}/#{size}/#{user.uploaded_avatar_id}.png" elsif upload # TODO broken with S3 (should retrun a permanent redirect) - original = Discourse.store.path_for(user.uploaded_avatar) + original = Discourse.store.path_for(upload) if File.exists?(original) optimized = OptimizedImage.create_for( - user.uploaded_avatar, + upload, size, size, allow_animation: SiteSetting.allow_animated_avatars diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index f9cf01ae8..310a991fe 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -7,7 +7,7 @@ class UsersController < ApplicationController skip_before_filter :authorize_mini_profiler, only: [:avatar] skip_before_filter :check_xhr, only: [:show, :password_reset, :update, :activate_account, :authorize_email, :user_preferences_redirect, :avatar, :my_redirect] - before_filter :ensure_logged_in, only: [:username, :update, :change_email, :user_preferences_redirect, :upload_user_image, :toggle_avatar, :clear_profile_background, :destroy] + before_filter :ensure_logged_in, only: [:username, :update, :change_email, :user_preferences_redirect, :upload_user_image, :pick_avatar, :clear_profile_background, :destroy] before_filter :respond_to_suspicious_request, only: [:create] # we need to allow account creation with bad CSRF tokens, if people are caching, the CSRF token on the @@ -364,12 +364,18 @@ class UsersController < ApplicationController end end - def toggle_avatar - params.require(:use_uploaded_avatar) + def pick_avatar + params.require(:upload_id) user = fetch_user_from_params guardian.ensure_can_edit!(user) + upload_id = params[:upload_id] - user.use_uploaded_avatar = params[:use_uploaded_avatar] + user.uploaded_avatar_id = upload_id + + # ensure we associate the custom avatar properly + unless user.user_avatar.contains_upload?(upload_id) + user.user_avatar.custom_upload_id = upload_id + end user.save! render nothing: true @@ -421,8 +427,7 @@ class UsersController < ApplicationController end def upload_avatar_for(user, upload) - user.upload_avatar(upload) - render json: { url: upload.url, width: upload.width, height: upload.height } + render json: { upload_id: upload.id, url: upload.url, width: upload.width, height: upload.height } end def upload_profile_background_for(user, upload) diff --git a/app/jobs/regular/create_missing_avatars.rb b/app/jobs/regular/create_missing_avatars.rb deleted file mode 100644 index e81429286..000000000 --- a/app/jobs/regular/create_missing_avatars.rb +++ /dev/null @@ -1,10 +0,0 @@ -module Jobs - class CreateMissingAvatars < Jobs::Base - def execute(args) - User.find_each do |u| - u.refresh_avatar - u.save - end - end - end -end diff --git a/app/jobs/scheduled/clean_up_uploads.rb b/app/jobs/scheduled/clean_up_uploads.rb index 503662b04..fb9c63054 100644 --- a/app/jobs/scheduled/clean_up_uploads.rb +++ b/app/jobs/scheduled/clean_up_uploads.rb @@ -6,14 +6,15 @@ module Jobs def execute(args) return unless SiteSetting.clean_up_uploads? - uploads_used_in_posts = PostUpload.uniq.pluck(:upload_id) - uploads_used_as_avatars = User.uniq.where('uploaded_avatar_id IS NOT NULL').pluck(:uploaded_avatar_id) uploads_used_as_profile_backgrounds = User.uniq.where("profile_background IS NOT NULL AND profile_background != ''").pluck(:profile_background) - + grace_period = [SiteSetting.clean_orphan_uploads_grace_period_hours, 1].max Upload.where("created_at < ?", grace_period.hour.ago) - .where("id NOT IN (?)", uploads_used_in_posts + uploads_used_as_avatars) + .where("id NOT IN (SELECT upload_id from post_uploads)") + .where("id NOT IN (SELECT system_upload_id from post_uploads)") + .where("id NOT IN (SELECT custom_upload_id from post_uploads)") + .where("id NOT IN (SELECT gravatar_upload_id from post_uploads)") .where("url NOT IN (?)", uploads_used_as_profile_backgrounds) .find_each do |upload| upload.destroy diff --git a/app/jobs/scheduled/create_missing_avatars.rb b/app/jobs/scheduled/create_missing_avatars.rb new file mode 100644 index 000000000..c7d0d0381 --- /dev/null +++ b/app/jobs/scheduled/create_missing_avatars.rb @@ -0,0 +1,15 @@ +module Jobs + class CreateMissingAvatars < Jobs::Scheduled + every 1.hour + def execute(args) + User.where(uploaded_avatar_id: nil).find_each do |u| + u.refresh_avatar + u.save + end + + UserAvatar.where(system_upload_id: nil).find_each do |a| + a.update_system_avatar! + end + end + end +end diff --git a/app/models/user.rb b/app/models/user.rb index 51b6f33ae..9d924f294 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -354,7 +354,7 @@ class User < ActiveRecord::Base def self.avatar_template(username,uploaded_avatar_id) id = uploaded_avatar_id || -1 username ||= "" - "/avatar/#{username.downcase}/{size}/#{id}.png" + "/user_avatar/#{username.downcase}/{size}/#{id}.png" end def avatar_template @@ -547,13 +547,9 @@ class User < ActiveRecord::Base created_at > 1.day.ago end - def upload_avatar(upload) - self.uploaded_avatar_template = nil - self.uploaded_avatar = upload - self.use_uploaded_avatar = true - self.save! - end - + # TODO this is a MESS + # at most user table should have profile_background_upload_id + # best case is to move this to another table def upload_profile_background(upload) self.profile_background = upload.url self.save! @@ -631,7 +627,11 @@ class User < ActiveRecord::Base avatar.update_system_avatar! if !avatar.system_upload_id || username_changed? end - self.uploaded_avatar_id = (avatar.gravatar_upload_id || avatar.system_upload_id) unless uploaded_avatar_id + desired_avatar_id = avatar.gravatar_upload_id || avatar.system_upload_id + + if !self.uploaded_avatar_id && desired_avatar_id + self.update_column(:uploaded_avatar_id, desired_avatar_id) + end end protected @@ -789,7 +789,6 @@ end # dynamic_favicon :boolean default(FALSE), not null # title :string(255) # use_uploaded_avatar :boolean default(FALSE) -# uploaded_avatar_template :string(255) # uploaded_avatar_id :integer # email_always :boolean default(FALSE), not null # mailing_list_mode :boolean default(FALSE), not null diff --git a/app/models/user_avatar.rb b/app/models/user_avatar.rb index 401ea3c3c..437f07949 100644 --- a/app/models/user_avatar.rb +++ b/app/models/user_avatar.rb @@ -27,10 +27,13 @@ class UserAvatar < ActiveRecord::Base upload = Upload.create_for(user.id, tempfile, 'gravatar.png', File.size(tempfile.path)) - gravatar_upload.destroy! if gravatar_upload - self.gravatar_upload = upload - save! - rescue OpenURI::HTTPError + if gravatar_upload_id != upload.id + gravatar_upload.try(:destroy!) + self.gravatar_upload = upload + save! + else + gravatar_upload + end save! ensure tempfile.unlink if tempfile diff --git a/app/serializers/user_action_serializer.rb b/app/serializers/user_action_serializer.rb index 35d4f5d8c..732d1837e 100644 --- a/app/serializers/user_action_serializer.rb +++ b/app/serializers/user_action_serializer.rb @@ -67,17 +67,4 @@ class UserActionSerializer < ApplicationSerializer object.action_type == UserAction::EDIT end - private - - def avatar_for(user_id, email, use_uploaded_avatar, uploaded_avatar_template, uploaded_avatar_id) - # NOTE: id is required for cases where the template is blank (during initial population) - User.new( - id: user_id, - email: email, - use_uploaded_avatar: use_uploaded_avatar, - uploaded_avatar_template: uploaded_avatar_template, - uploaded_avatar_id: uploaded_avatar_id - ).avatar_template - end - end diff --git a/config/routes.rb b/config/routes.rb index af88c444f..f9b9ec4ba 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -202,7 +202,7 @@ Discourse::Application.routes.draw do get "users/:username/avatar(/:size)" => "users#avatar", constraints: {username: USERNAME_ROUTE_FORMAT} # LEGACY ROUTE post "users/:username/preferences/avatar" => "users#upload_avatar", constraints: {username: USERNAME_ROUTE_FORMAT} # LEGACY ROUTE post "users/:username/preferences/user_image" => "users#upload_user_image", constraints: {username: USERNAME_ROUTE_FORMAT} - put "users/:username/preferences/avatar/toggle" => "users#toggle_avatar", constraints: {username: USERNAME_ROUTE_FORMAT} + put "users/:username/preferences/avatar/pick" => "users#pick_avatar", constraints: {username: USERNAME_ROUTE_FORMAT} put "users/:username/preferences/profile_background/clear" => "users#clear_profile_background", constraints: {username: USERNAME_ROUTE_FORMAT} get "users/:username/invited" => "users#invited", constraints: {username: USERNAME_ROUTE_FORMAT} post "users/:username/send_activation_email" => "users#send_activation_email", constraints: {username: USERNAME_ROUTE_FORMAT} @@ -211,6 +211,10 @@ Discourse::Application.routes.draw do get "users/:username/badges" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT} delete "users/:username" => "users#destroy", constraints: {username: USERNAME_ROUTE_FORMAT} + post "user_avatar/:username/refresh_gravatar" => "user_avatars#refresh_gravatar" + get "user_avatar/:username/:size/:version.png" => "user_avatars#show", format: false + + get "uploads/:site/:id/:sha.:extension" => "uploads#show", constraints: {site: /\w+/, id: /\d+/, sha: /[a-z0-9]{15,16}/i, extension: /\w{2,}/} post "uploads" => "uploads#create" @@ -366,8 +370,6 @@ Discourse::Application.routes.draw do post "draft" => "draft#update" delete "draft" => "draft#destroy" - get "avatar/:username/:size/:version.png" => "avatar#show", format: false - get "cdn_asset/:site/*path" => "static#cdn_asset", format: false get "robots.txt" => "robots_txt#index" diff --git a/db/fixtures/005_users.rb b/db/fixtures/005_users.rb index dda16fe7f..5ba7bfe93 100644 --- a/db/fixtures/005_users.rb +++ b/db/fixtures/005_users.rb @@ -23,8 +23,3 @@ User.seed do |u| u.email_private_messages = false u.trust_level = TrustLevel.levels[:elder] end - -# download avatars for existing users -if UserAvatar.count < User.count - Jobs.enqueue(:create_missing_avatars) -end diff --git a/db/migrate/20140522003151_add_user_avatars.rb b/db/migrate/20140522003151_add_user_avatars.rb index 8632d912e..4d96a1b05 100644 --- a/db/migrate/20140522003151_add_user_avatars.rb +++ b/db/migrate/20140522003151_add_user_avatars.rb @@ -1,5 +1,5 @@ class AddUserAvatars < ActiveRecord::Migration - def change + def up create_table :user_avatars do |t| t.integer :user_id, null: false t.integer :system_upload_id @@ -8,5 +8,17 @@ class AddUserAvatars < ActiveRecord::Migration t.datetime :last_gravatar_download_attempt t.timestamps end + + add_index :user_avatars, [:user_id] + + execute <