Modified: branches/event_logging/app/helpers/application_helper.rb (2032 => 2033)
--- branches/event_logging/app/helpers/application_helper.rb 2008-12-04 18:09:51 UTC (rev 2032)
+++ branches/event_logging/app/helpers/application_helper.rb 2008-12-05 12:37:35 UTC (rev 2033)
@@ -1747,7 +1747,7 @@
puts "=============== GROUPING ================="
# END DEBUG
- related_activity_loggable_ids = []
+ related_objects = []
array_ids_to_delete = []
grouping_happened = false
@@ -1767,9 +1767,9 @@
new_event = events_unique[i]
reset_required = true
- # check if grouping will happen
+
+ # DEBUG
if (new_event.created_at - base_event.created_at <= EVENT_GROUPING_TIMEFRAME)
- # DEBUG
puts "timeframe match: seq_start(#{seq_start_idx}) -> current(#{i})"
puts "new: " + new_event.action + " base: " + base_event.action + " #{ new_event.action == base_event.action}"
puts "new: " + new_event.activity_loggable_type + " base: " + base_event.activity_loggable_type + " #{ new_event.activity_loggable_type == base_event.activity_loggable_type}"
@@ -1781,31 +1781,25 @@
puts "-- first condition of further check: #{["Tagging"].include? new_event.activity_loggable_type}"
puts "-- second condition of further check: #{new_event.action == "create"}"
puts "\n"
+ end
+ # END DEBUG
+
+
+ # check if grouping will happen
+ grouping_allowed, related_object = group_event_with_base?(new_event, base_event)
+ if grouping_allowed
+ # events are within the correct timeframe and potentially can be grouped
+ # DEBUG
+ puts "grouping should happen"
# END DEBUG
- # events are within the correct timeframe, potentially can be grouped
- if group_event_with_base?(true, new_event, base_event)
-
- # DEBUG
- puts "grouping should happen"
- # END DEBUG
-
- seq_timestamp = [new_event.created_at, new_event.updated_at]
- related_activity_loggable_ids << new_event.activity_loggable_id
- array_ids_to_delete << i
-
- grouping_happened = true
- reset_required = false
-
- elsif group_event_with_base?(false, new_event, base_event)
-
- seq_timestamp = [new_event.created_at, new_event.updated_at]
- array_ids_to_delete << i
-
- grouping_happened = true
- reset_required = false
- end
+ seq_timestamp = [new_event.created_at, new_event.updated_at]
+ related_objects << related_object
+ array_ids_to_delete << i
+
+ grouping_happened = true
+ reset_required = false
end
if reset_required
@@ -1818,7 +1812,7 @@
events_unique[seq_start_idx].created_at = seq_timestamp[0]
events_unique[seq_start_idx].updated_at = seq_timestamp[1]
- events_unique[seq_start_idx] = [events_unique[seq_start_idx], related_activity_loggable_ids]
+ events_unique[seq_start_idx] = [events_unique[seq_start_idx], related_objects]
# delete all (now) redundant elements
array_ids_to_delete.each do |del_idx|
events_unique.delete_at(del_idx)
@@ -1829,7 +1823,7 @@
seq_start_idx = i # current element becomes the start of the sequence
base_event = events_unique[seq_start_idx]
seq_timestamp = nil
- related_activity_loggable_ids = []
+ related_objects = []
array_ids_to_delete = []
grouping_happened = false
end
@@ -1846,7 +1840,7 @@
events_unique[seq_start_idx].created_at = seq_timestamp[0]
events_unique[seq_start_idx].updated_at = seq_timestamp[1]
- events_unique[seq_start_idx] = [events_unique[seq_start_idx], related_activity_loggable_ids]
+ events_unique[seq_start_idx] = [events_unique[seq_start_idx], related_objects]
# delete all (now) redundant elements
array_ids_to_delete.each do |del_idx|
events_unique.delete_at(del_idx)
@@ -1904,11 +1898,11 @@
if log_entry_container.class.name == "Array"
# if log_entry_container holds an array, the zeroth element is the actual log_entry object!
log_entry = log_entry_container[0]
- extra_ids = log_entry_container[1]
+ extra_objects = log_entry_container[1]
else
# the log entry container should be the log_entry itself
log_entry = log_entry_container
- extra_ids = []
+ extra_objects = []
end
rtn = [] # despite this, NIL will be returned on errors / when news entry not to be shown for current user
@@ -2275,18 +2269,42 @@
when "Bookmark"
if action == "create"
begin
- # information from the actual bookmark instance is not used directly, however this check is required to ensure that -
- # RecordNotFound exception will be thrown and the news item won't appear if the bookmark was subsequently removed after creation
- bookmark = Bookmark.find(log_entry.activity_loggable_id)
- object, object_path = evaluate_object_instance_and_path(log_entry.referenced_type, log_entry.referenced_id)
- object_visible_name = contributable_name_from_instance(object)
+ # process potentially multiple bookmarks
+ all_bookmark_ids = [log_entry.activity_loggable_id]
+ extra_objects.each do |extra_bookmark|
+ # all of the "extra objects" will be bookmarks, no need to check the type
+ all_bookmark_ids << extra_bookmark[1]
+ end
+ not_found_bookmark_count = 0
+ bookmarked_items_strings = []
- # the news item to be displayed if the current viewer is allowed to see the affected contributable
- authorized = ( my_event || object.authorized?("view", current_viewer) )
+ all_bookmark_ids.each do |bookmark_id|
+ # protected block required to ensure that if several - not all bookmarks are missing, remaining still get displayed
+ begin
+ bookmark = Bookmark.find(bookmark_id)
+
+ object, object_path = evaluate_object_instance_and_path(bookmark.bookmarkable_type, bookmark.bookmarkable_id)
+ object_visible_name = contributable_name_from_instance(object)
+
+ # the news item to be displayed if the current viewer is allowed to see the affected contributable(s)
+ authorized = ( my_event || object.authorized?("view", current_viewer) )
+
+ if authorized
+ bookmarked_items_strings << [link_to(object_visible_name, object_path) + " " + model_visible_name(object.class.name, true, object)]
+ end
+ rescue ActiveRecord::RecordNotFound
+ not_found_bookmark_count += 1
+ end
+ end
- if authorized
- rtn << [timestamp, "#{culprit_link} <span class='news_feed_action'>added</span> #{link_to object_visible_name, object_path} #{model_visible_name(log_entry.referenced_type.to_s, true, object)} to their #{link_to "favourites", user_path(log_entry.culprit_id) + "/favourites"}.", "Favourites"]
+ if not_found_bookmark_count == all_bookmark_ids.length
+ raise ActiveRecord::RecordNotFound, "None of the bookmarks found"
end
+
+ # authorization was done when this array was filled up - if it's empty, nothing to display (potentially because of the authorization)
+ unless bookmarked_items_strings.empty?
+ rtn << [timestamp, "#{culprit_link} <span class='news_feed_action'>added</span> #{bookmarked_items_strings.join(", ")} to their #{link_to "favourites", user_path(log_entry.culprit_id) + "/favourites"}.", "Favourites"]
+ end
rescue ActiveRecord::RecordNotFound
# do nothing, but don't display the news entry for missing bookmark / object
end
@@ -2403,35 +2421,40 @@
when "Tagging"
if action == "create"
begin
- # process potentially multiple tags
- all_tagging_ids = [log_entry.activity_loggable_id]
- all_tagging_ids.concat(extra_ids)
- not_found_tag_count = 0
- tag_strings = []
-
- all_tagging_ids.each do |tagging_id|
- # protected block required to ensure that if several - not all tags are missing, remaining still get displayed
- begin
- tagging = Tagging.find(tagging_id)
- tag = Tag.find(tagging.tag_id)
- tag_strings << ["\"" + link_to(tag.name, tag_path(tag.id)) + "\""]
- rescue ActiveRecord::RecordNotFound
- not_found_tag_count += 1
- end
- end
-
- if not_found_tag_count == all_tagging_ids.length
- raise ActiveRecord::RecordNotFound, "None of the tags found"
- end
-
-
object, object_path = evaluate_object_instance_and_path(log_entry.referenced_type, log_entry.referenced_id)
object_visible_name = contributable_name_from_instance(object)
# the news item to be displayed if the current viewer is allowed to see the affected contributable
+ # (it's fine to do authorization only once, because all tags refer to the same object)
authorized = ( my_event || object.authorized?("view", current_viewer) )
+ # multiple tag processing is quite DB intensive, so if the object not authorized for
+ # current viewer, no need to do anything further
if authorized
+ # process potentially multiple tags
+ all_tagging_ids = [log_entry.activity_loggable_id]
+ extra_objects.each do |extra_tagging|
+ # all of the "extra objects" will be taggings, no need to check the type
+ all_tagging_ids << extra_tagging[1]
+ end
+ not_found_tag_count = 0
+ tag_strings = []
+
+ all_tagging_ids.each do |tagging_id|
+ # protected block required to ensure that if several - not all tags are missing, remaining still get displayed
+ begin
+ tagging = Tagging.find(tagging_id)
+ tag = Tag.find(tagging.tag_id)
+ tag_strings << ["\"" + link_to(tag.name, tag_path(tag.id)) + "\""]
+ rescue ActiveRecord::RecordNotFound
+ not_found_tag_count += 1
+ end
+ end
+
+ if not_found_tag_count == all_tagging_ids.length
+ raise ActiveRecord::RecordNotFound, "None of the tags found"
+ end
+
rtn << [timestamp, "#{culprit_link} <span class='news_feed_action'>tagged</span> #{link_to object_visible_name, object_path} #{model_visible_name(log_entry.referenced_type.to_s, true, object)} with #{tag_strings.join(", ")}.", "Tags"]
end
rescue ActiveRecord::RecordNotFound
@@ -2540,28 +2563,36 @@
end
- # this method assumes that the two events are within a certain timeframe and decides if
- # these can be grouped or not;
- # "should_have_accummulated_ids" parameter chooses between two types of grouping behaviour:
- # -- one option is to pick the latest of all events (because they don't add any new information) (false)
- # -- another option is to accummulate the items the news entries are pointing to and present them as one (true)
- def group_event_with_base?(should_have_accummulated_ids, new_event, base_event)
+ # This method decides whether the "new_event" can be grouped with "base_event";
+ # (Assumption is made that the two events are within a certain timeframe to allow grouping)
+ #
+ # Two types of grouping behaviour is possible:
+ # -- one option is to pick the latest of all events (because they don't add any new information) (like for "Profile" updates)
+ # -- another option is to accummulate the items the news entries are pointing to and present them as one (like for "Tagging" - "X tagged with A,B,C")
+ #
+ # Method returns an array in the form: [allow_grouping, [related_object_type, related_object_id]]
+ # * allow_grouping - boolean value; "true" when the events should be grouped;
+ # * related_object_type/ID - related object (like tag "B") which should be grouped with the object in the base event (like tag "A")
+ def group_event_with_base?(new_event, base_event)
ans = false
+ related_object = []
- if should_have_accummulated_ids
+ if (new_event.created_at - base_event.created_at <= EVENT_GROUPING_TIMEFRAME)
# action "create" && "Tagging" && ActivityLoggableType match (IDs can vary) && CulpritType/CulpritID match && ReferencedType/ReferencedID match
if ((["Tagging"].include? new_event.activity_loggable_type) && new_event.action == "create" &&
new_event.action == base_event.action && new_event.activity_loggable_type == base_event.activity_loggable_type &&
new_event.culprit_type == base_event.culprit_type && new_event.culprit_id == base_event.culprit_id &&
new_event.referenced_type == base_event.referenced_type && new_event.referenced_id == base_event.referenced_id)
ans = true
+ related_object = ["Tagging", new_event.activity_loggable_id]
# action "create" && "Bookmark" && ActivityLoggableType match (IDs can vary) && CulpritType/CulpritID match --> Referenced :: Any type / ID
elsif ((["Bookmark"].include? new_event.activity_loggable_type) && new_event.action == "create" &&
new_event.action == base_event.action && new_event.activity_loggable_type == base_event.activity_loggable_type &&
new_event.culprit_type == base_event.culprit_type && new_event.culprit_id == base_event.culprit_id)
ans = true
-
+ related_object = ["Bookmark", new_event.activity_loggable_id]
+
# action "create" && "Creditation|Attribution" && ActivityLoggableType match (IDs can vary) && CulpritType/CulpritID match --> Referenced :: Any type / ID
# but need to add more strict check on the timestamp - will attempt to group only creditations / attributions at exact same date / time
elsif ((["Creditation", "Attribution"].include? new_event.activity_loggable_type) && new_event.action == "create" &&
@@ -2569,18 +2600,20 @@
new_event.culprit_type == base_event.culprit_type && new_event.culprit_id == base_event.culprit_id &&
new_event.created_at == base_event.created_at && new_event.updated_at == base_event.updated_at)
ans = true
- end
- else
+ related_object = [new_event.activity_loggable_type, new_event.activity_loggable_id]
+
# action "update" && "Profile" && ActivityLoggableType match && CulpritType/CulpritID match && ReferencedType/ReferencedID match
- if ((["Profile"].include? new_event.activity_loggable_type) && new_event.action == "update" &&
+ elsif ((["Profile"].include? new_event.activity_loggable_type) && new_event.action == "update" &&
new_event.action == base_event.action && new_event.activity_loggable_type == base_event.activity_loggable_type &&
new_event.culprit_type == base_event.culprit_type && new_event.culprit_id == base_event.culprit_id &&
new_event.referenced_type == base_event.referenced_type && new_event.referenced_id == base_event.referenced_id)
- ans = true
+ ans = true
+ # related_object not required in this case
end
+
end
- return ans
+ return [ans, related_object]
end
######################################################