Diff
Modified: branches/invitation_throttling/app/controllers/application.rb (2014 => 2015)
--- branches/invitation_throttling/app/controllers/application.rb 2008-11-28 17:10:15 UTC (rev 2014)
+++ branches/invitation_throttling/app/controllers/application.rb 2008-11-28 17:40:01 UTC (rev 2015)
@@ -38,100 +38,7 @@
return res
end
-
- # the single point in the application governing validation of all features that have
- # limited allowance of usage (e.g. 5 messages a day, etc)
- def check_activity_limit(contributor, limit_feature, update_counter=true)
- time_now = Time.now
- limit_save_required = false
-
- if (limit = ActivityLimit.find(:first, :conditions => ["contributor_type = ? AND contributor_id = ? AND limit_feature = ?", contributor.class.name, contributor.id, limit_feature]))
- # limit exists - check its validity
- if (limit.limit_frequency && limit.reset_after && time_now > limit.reset_after)
- # "reset_after" / "limit_frequency" are not NULL - so the limit is periodic;
- # now it's the time to reset the counter to zero - no matter what its value was before
- # (this will never be executed for non-periodic counters)
- limit.current_count = 0
- limit.reset_after = time_now + limit.limit_frequency.hours
- limit_save_required = true
- # also check if the contributor needs to be "promoted" to the next level --
- # e.g. in the first month of membership on myExperiment one can send 10 messages daily,
- # but after that can send 15 (because the user becomes more "trusted")
- if (limit.promote_after && time_now > limit.promote_after)
- absolute_max_limit_value = eval("#{limit_feature.upcase}_LIMIT_MAX_VALUE")
- limit_increment_value = eval("#{limit_feature.upcase}_LIMIT_PROMOTE_INCREMENT")
- promote_every = eval("#{limit_feature.upcase}_LIMIT_PROMOTE_EVERY")
-
- if limit_increment_value
- if absolute_max_limit_value
- # absolute max value set -->
- # increase the limit only if not exceeded absolute maximum just yet
- if (limit.limit_max < absolute_max_limit_value)
- limit.limit_max += limit_increment_value
- limit.promote_after = (promote_every ? (time_now + promote_every.days) : nil)
- else
- # absolute maximum already reached / exceeded, disable further promotions
- limit.promote_after = nil
- end
-
- # make sure that it's not set to exceed the absolute maximum
- # (which can happen if increment is not factor of the absolute maximum value)
- if (limit.limit_max > absolute_max_limit_value)
- limit.limit_max = absolute_max_limit_value
- end
- else
- # absolute value not set --> simply increment
- limit.limit_max += limit_increment_value
- limit.promote_after = (promote_every ? (time_now + promote_every.days) : nil)
- end
- else
- # increment not set - this will be a one-time promotion
- # (if the absolute max value is set - set limit to it; if not - the feature becomes unlimited)
- limit.limit_max = absolute_max_limit_value
- limit.promote_after = nil
- end
- end # END of PROMOTION code
-
- end # END of COUNTER RESET code
-
- else
- # limit doesn't exist yet - create it, then proceed to validation and saving
- limit_frequency = eval("#{limit_feature.upcase}_LIMIT_FREQUENCY")
- promote_every = eval("#{limit_feature.upcase}_LIMIT_PROMOTE_EVERY")
-
- limit = ActivityLimit.new(:contributor_type => contributor.class.name, :contributor_id => contributor.id,
- :limit_feature => limit_feature,
- :limit_max => eval("#{limit_feature.upcase}_LIMIT_START_VALUE"),
- :limit_frequency => limit_frequency,
- :reset_after => (limit_frequency ? (time_now + limit_frequency.hours) : nil),
- :promote_after => (promote_every ? (time_now + promote_every.days) : nil),
- :current_count => 0)
-
- limit_save_required = true
- end
-
-
- # decide if the requested action is allowed - check on the current counter value
- action_allowed = true
- if limit.limit_max
- # (NULL in "limit_max" would mean unlimited allowance - not this case)
- # deny the action if the "current_count" is equal / exceeded the "limit_max" value
- action_allowed = false if (limit.current_count >= limit.limit_max)
- end
-
- # update counter for the "current" action
- if action_allowed && update_counter
- limit.current_count += 1
- limit_save_required = true
- end
- limit.save if limit_save_required # saves all changes (including counter resets, etc) if any were made
-
- # return if action is allowed / denied and when the next reset is going to be (nil for non-periodic counters)
- return [action_allowed, (limit.reset_after ? (limit.reset_after - time_now) : nil)]
- end
-
-
def formatted_timespan(time_period)
# Takes a period of time in seconds and returns it in human-readable form (down to minutes)
# from (http://www.postal-code.com/binarycode/category/devruby/)
Modified: branches/invitation_throttling/app/controllers/messages_controller.rb (2014 => 2015)
--- branches/invitation_throttling/app/controllers/messages_controller.rb 2008-11-28 17:10:15 UTC (rev 2014)
+++ branches/invitation_throttling/app/controllers/messages_controller.rb 2008-11-28 17:40:01 UTC (rev 2015)
@@ -81,7 +81,7 @@
flash[:error] = "You cannot send a message to yourself"
format.html { redirect_to new_message_url }
end
- elsif (allowed_plus_timespan = check_activity_limit(current_user, "internal_message", false))[0]
+ elsif (allowed_plus_timespan = ActivityLimit.check_limit(current_user, "internal_message", false))[0]
# the user is allowed to send messages - limit not yet reached; show the new message screen
# (but the counter is not updated just yet - the user might not send the message after all,
# so this is a mere validation - which saves user from typing the message in and learning that
@@ -115,7 +115,7 @@
# POST /messages
def create
# check if sending is allowed and increment the message counter
- sending_allowed = check_activity_limit(current_user, "internal_message")[0]
+ sending_allowed = ActivityLimit.check_limit(current_user, "internal_message")[0]
if sending_allowed
@message = Message.new(params[:message])
Modified: branches/invitation_throttling/app/models/activity_limit.rb (2014 => 2015)
--- branches/invitation_throttling/app/models/activity_limit.rb 2008-11-28 17:10:15 UTC (rev 2014)
+++ branches/invitation_throttling/app/models/activity_limit.rb 2008-11-28 17:40:01 UTC (rev 2015)
@@ -1,2 +1,95 @@
class ActivityLimit < ActiveRecord::Base
+
+ # the single point in the application governing validation of all features that have
+ # limited allowance of usage (e.g. 5 messages a day, etc)
+ def self.check_limit(contributor, limit_feature, update_counter=true)
+ time_now = Time.now
+ limit_save_required = false
+
+ if (limit = ActivityLimit.find(:first, :conditions => ["contributor_type = ? AND contributor_id = ? AND limit_feature = ?", contributor.class.name, contributor.id, limit_feature]))
+ # limit exists - check its validity
+ if (limit.limit_frequency && limit.reset_after && time_now > limit.reset_after)
+ # "reset_after" / "limit_frequency" are not NULL - so the limit is periodic;
+ # now it's the time to reset the counter to zero - no matter what its value was before
+ # (this will never be executed for non-periodic counters)
+ limit.current_count = 0
+ limit.reset_after = time_now + limit.limit_frequency.hours
+ limit_save_required = true
+
+ # also check if the contributor needs to be "promoted" to the next level --
+ # e.g. in the first month of membership on myExperiment one can send 10 messages daily,
+ # but after that can send 15 (because the user becomes more "trusted")
+ if (limit.promote_after && time_now > limit.promote_after)
+ absolute_max_limit_value = eval("#{limit_feature.upcase}_LIMIT_MAX_VALUE")
+ limit_increment_value = eval("#{limit_feature.upcase}_LIMIT_PROMOTE_INCREMENT")
+ promote_every = eval("#{limit_feature.upcase}_LIMIT_PROMOTE_EVERY")
+
+ if limit_increment_value
+ if absolute_max_limit_value
+ # absolute max value set -->
+ # increase the limit only if not exceeded absolute maximum just yet
+ if (limit.limit_max < absolute_max_limit_value)
+ limit.limit_max += limit_increment_value
+ limit.promote_after = (promote_every ? (time_now + promote_every.days) : nil)
+ else
+ # absolute maximum already reached / exceeded, disable further promotions
+ limit.promote_after = nil
+ end
+
+ # make sure that it's not set to exceed the absolute maximum
+ # (which can happen if increment is not factor of the absolute maximum value)
+ if (limit.limit_max > absolute_max_limit_value)
+ limit.limit_max = absolute_max_limit_value
+ end
+ else
+ # absolute value not set --> simply increment
+ limit.limit_max += limit_increment_value
+ limit.promote_after = (promote_every ? (time_now + promote_every.days) : nil)
+ end
+ else
+ # increment not set - this will be a one-time promotion
+ # (if the absolute max value is set - set limit to it; if not - the feature becomes unlimited)
+ limit.limit_max = absolute_max_limit_value
+ limit.promote_after = nil
+ end
+ end # END of PROMOTION code
+
+ end # END of COUNTER RESET code
+
+ else
+ # limit doesn't exist yet - create it, then proceed to validation and saving
+ limit_frequency = eval("#{limit_feature.upcase}_LIMIT_FREQUENCY")
+ promote_every = eval("#{limit_feature.upcase}_LIMIT_PROMOTE_EVERY")
+
+ limit = ActivityLimit.new(:contributor_type => contributor.class.name, :contributor_id => contributor.id,
+ :limit_feature => limit_feature,
+ :limit_max => eval("#{limit_feature.upcase}_LIMIT_START_VALUE"),
+ :limit_frequency => limit_frequency,
+ :reset_after => (limit_frequency ? (time_now + limit_frequency.hours) : nil),
+ :promote_after => (promote_every ? (time_now + promote_every.days) : nil),
+ :current_count => 0)
+
+ limit_save_required = true
+ end
+
+
+ # decide if the requested action is allowed - check on the current counter value
+ action_allowed = true
+ if limit.limit_max
+ # (NULL in "limit_max" would mean unlimited allowance - not this case)
+ # deny the action if the "current_count" is equal / exceeded the "limit_max" value
+ action_allowed = false if (limit.current_count >= limit.limit_max)
+ end
+
+ # update counter for the "current" action
+ if action_allowed && update_counter
+ limit.current_count += 1
+ limit_save_required = true
+ end
+ limit.save if limit_save_required # saves all changes (including counter resets, etc) if any were made
+
+ # return if action is allowed / denied and when the next reset is going to be (nil for non-periodic counters)
+ return [action_allowed, (limit.reset_after ? (limit.reset_after - time_now) : nil)]
+ end
+
end