I had a need to generate a bunch of activity on our current site for our migration. This would be a killer feature for Activity if it could be generalized, so I'm starting an issue here on it in hopes that someone has time to run with it a bit further. The current script will find nodes, comments, and approved friendships (for flag_friend) from the lat 30 days and generate activity based upon the current Activity publisher templates I have setup in my system.
Activity publisher templates for this script:
-
Hook: nodeapi Operation: insert Author template: You created a new [type-name]: <a href="/node/[nid]">[title]</a> Public template: <a href="/user/[author-uid]">[author-name]</a> created a new [type-name]: <a href="/node/[nid]">[title]</a> -
Hook: comment Operation: insert Author template: You commented on <a href="/node/[comment-nid]">[comment-node-title]</a>. Public template: <a href="/user/[comment-author-uid]">[comment-author-name]</a> commented on <a href="/node/[comment-nid]">[comment-node-title]</a>. -
Hook: flag_friend Operation: approve Requestor template: You are now friends with <a href="[requestee-url]">[requestee]</a>. Requestee template: <a href="[requestor-url]">[requestor]</a> is now friends with you. Public template:<a href="[requestor-url]">[requestor]</a> is now friends with <a href="[requestee-url]">[requestee]</a>.
NOTE: This issue is for development purposes only. Please do not ask a bunch of question on how to use this. Only participate in this issue if you are helping to develop the script for more general application/into a module.
| Comment | File | Size | Author |
|---|---|---|---|
| #21 | activity_63854-21.patch | 20.38 KB | Scott Reynolds |
| #20 | activity_63854-20.patch | 17.36 KB | Scott Reynolds |
| #19 | activity_63854-18.patch | 13.13 KB | Scott Reynolds |
| #13 | activity_63854-14.patch | 12.88 KB | Scott Reynolds |
| #12 | activity_63854-12.patch | 8.11 KB | Scott Reynolds |
Comments
Comment #1
sirkitree commentedI forgot to add a comment about trigger module. Since I'm using the api's therein - there is a problem when batching nodeapi operations because ti caches the $op and doesn't allow you to reset that cache programatically - uhg. Attached is an update with a comment on where to do this.
Comment #2
entendu commentedIn case anyone's wondering where the [comment-node-title] token came from:
http://drupal.org/node/321487
Comment #3
pribeh commentedkiller. subscribing.
Comment #4
youkho commentedNeed it now xD
Comment #5
pribeh commentedTested it and I can report that it works great. Will try to figure out how to log FBS statuses. and report back
Comment #6
pribeh commentedThanks to publicmind we have a modified version of sirkitrees script that generates activity for the Facebook Style Statuses module and a yet unreleased submodule for FBSS. The unreleased submodule for FBSS (which is totally wicked) will be released on Drupal.org in due time and at publicmind's discretion. Hope this might help the issue at hand.
The attached script runs like a module. It generates activity for Facebook statuses as well as nodes. For anyone just browsing for a temporary solution to do just this: drop the folder (once unzipped) into your module directory and run it per usual. It runs the script and then shuts off. Thanks again to sirkitree for his hard work.
Comment #7
publicmind commentedThanks pribeh for posting it, I never got the time to do it. I hope it helps. :)
Comment #8
icecreamyou commentedCool, pribeh and publicmind. This will be useful.
Subscribing in case I can be useful (I'm the Facebook-style Statuses maintainer) and because I'd like to see this committed!
Comment #9
Scott Reynolds commentedThis is now broken as of this commit: http://drupal.org/cvs?commit=359596
I really want this in, so I will be working on it. I have a minor prototype working for node insert and comment insert. It needs work though.
Comment #10
gausarts commentedSubscribing. Thanks
Comment #11
Scott Reynolds commentedSo here is a first pass, it only works for nodeapi insert, the rest haven't been implemented.
What it fails todo is to delete the existing activity. And the reason for this is a little difficult.
When activity_record() is called it isn't told what aid has triggered. So it doesn't record that away in the {activity} table. Each regeneration is based on an aid, because the aid controls what templates to use, and what types are allowed. So when the batch is started, I would like it to DELETE FROM {activity} WHERE actions_id = X.
So to solve this, I'm thinking that instead of this
we do
Save it twice, the second time updates the existing record with the params. This puts the $aid in the params array which is then inserted into the $context that is sent to activity_record.
I know it is ugly, but it is ugly only once.
Comment #12
Scott Reynolds commentedattached is the patch. Because it adds a new menu item, please clear you menu cache.
And here is where you would find the link: http://skitch.com/supermanscott/ddssj/regenerate
Comment #13
Scott Reynolds commentedOnly node insert here but it does the 'hackish' trick to get the 'aid' into the parameters array that is passed into the activity_record(). This also has an update function, you will have to run it to make this work. It will not delete existing records that were created prior to this patch. I haven't come up with a scheme to determine that. It is pretty hard...
Comment #14
sirkitree commentedTested, and node insert regeneration works great!
As for resaving, I'm not sure we should really worry about that, at least for the first pass here. We originally wanted to implement this as a means to generate activity on a current site that maybe is upgrading, or never had activity to begin with. If we're keeping with that line of thinking then there are two things to address:
1) A site will not have activity already and therefor it doesn't matter if we update the original because there isn't one.
2) The term regenerate really shifts this concept from 'generating' a whole bunch of activity on a fresh site, to 'regenerating' activity based on the activity pattern.
So while I think that 'regenerate' is way more useful in the long run (situation where the activity pattern changes and we want to make all existing activity conform to the new pattern), it might lead us to a longer development cycle before we actually get a release out the door.
p.s. you'll notice i used the phrase 'activity pattern' instead of 'activity template'... I think this term is way more accurate and will be less likely to be confused with the template system.
Comment #15
sirkitree commentedSorry, cross post - I tested activity_63854-12.patch
Comment #16
pribeh commentedHi sirktiree,
Thanks so much for getting back to this. I guess I'm a little confused by your assertions in #14. I'm not sure I quite understand what you mean by 'activity pattern'. Couldn't we uninstall Activity to remove old activity records and then reinstall and run the generation/regeneration script to freshly generate Activity records for each existing nodes?
Comment #17
sirkitree commented@pribeh Yes, you could. What I'm talking about is the Activity Template. You create an Activity Template with the pattern of the message, housing tokens and other words to create a complete sentence when an activity record is generated. This feature would be really useful in that you could change the Activity Template's pattern (or activity pattern) and then regenerate all of the corresponding activity messages so that they conform to the changes you made to the pattern.
Comment #18
Scott Reynolds commentedHere is an updated patch, it adds Node View as a possible regeneration.
The notable change is in the api. In this patch, the list_callback returns the actor who did the action as opposed to the context_loader function. This is needed for the Node View because the uid doesn't match an object.
Comment #19
Scott Reynolds commentedThe api needs a review here.
Added
$info->list_callback that returns all the events that match the associated hook and op
$info->context_load_callback that loads the $context array that is passed into actions_do().
The list_callback returns an unkeyed array of the form
And the context_loader_callback returns an array mimicking the $context passed to actions_do.
Comment #20
Scott Reynolds commentedOk here is another updated patch, this time with comment insert and user insert.
It is currently fails to protect templates that cannot be regenerated. Things like node update, user view etc. Clicking regenerate on those will either
A.) produce a fail error or
B.) Delete all existing activity for that template and then produce a fail error
This needs to be handle and I think the cool and best way to do it is with a menu loader
This produces a semantically correct page not found when you click on an Activity template that cannot be regenerated. And you can use this function in the theme function to decide if you should show the regenerate link.
Comment #21
Scott Reynolds commentedOk here is another roll with that change mentioned, it only shows the regenerate link when it can actually regenerate.
This patch also introduces this: http://skitch.com/supermanscott/dd3g9/delete-checkbox which uses the bulk deletion needed for the regeneration into the delete template form. I couldn't resist...
The thing I see missing from this patch is an update to Developer.txt
Comment #22
sirkitree commentedI haven't tested the newest yet, but I'm wondering how this works with activity_comments? If there are comments on a particular activity and it is removed and regenerated, are the comments lost?
Comment #23
Scott Reynolds commentedYes the comments are lost and it would be very hard to remedy that. Comments are associated with the activity id. In order to regenerate, all previous activity are deleted and the new activity is created from scratch.
Maybe this is too aggressive. Maybe we just need to regenerate the messages. I will think about that for a little bit.
Comment #24
Scott Reynolds commentedHaving thought about it (re)generating messages and redoing existing messages are two distinct operations
1.) (re)generating does it for all events that match the specific type
2.) redoing existing messages just takes one or more messages and creates a new message(s) entries.
There is value in both. (re)generating allows a site to start from an existing database and log messages. It also provides an 'upgrade' path :-D
redoing existing messages allows for us todo the following
Which would be cool. I would like to address redoing messages in another ticket. It would use the same functions defined here, but would require re-factoring activity_record() function a lot and breaking it down into more separate steps.
Comment #25
sirkitree commentedYeah - I really don't think we should do the regeneration part - maybe save that for D7 or simply another feature request.
The generation part is a simple stop gap in lieu of an upgrade path because we don't want to tackle it, it's just too complex.
As for the loading, I'm wondering if there is a way to ensure that this is only ever run just once, so that regeneration is not possible. Maybe a seasoned developer tool that could progress on it's own or something, but present it in a UI that only allows it to happen on a site that has NO activity records present for now.
So while 'regenerate' is a really cool feature - it should be separate and we should narrow this to just 'generation' to get this to a point where we can make a release.
Comment #26
pribeh commentedAh, I can understand sirkitree's idea and agree for the most part. I really do need the ability to regenerate Activity messages on a site that has existing activity messages; but, with that said, I should be able to achieve this by simply (uninstalling and) reinstalling the module and generating new messages, correct? If that's the case, I'm totally cool with forgetting about the regeneration part. Otherwise, I'll need to find another solution.
Comment #27
Scott Reynolds commented@25 ok, so then when a user submits the new template, run the generation process. That work ?
Comment #28
Scott Reynolds commentedSo I worked a patch that allowed for the generation of messages when you create a new template only. But in testing, I realized that I would just delete existing template and their messages and then create a new template and generate from there.
I figured why make that difficult like that. Usability through obscurity? So I want to stick with the current patch. It presents a regenerate link to all templates that can be regenerated. All messages attached to that template are deleted and then generated from scratch.
I want to be able to generate messages if the node changes for instance, but that is clearly a followup to this issue. All the cards will be in place, just a minor re-factoring to make activity_record function less of a monster and we are there.
So Please test #21, I believe very strongly that it is the right way forward.
edit: Please test the patch in #21 as I believe that my previous comments have confused some people
Comment #29
pribeh commentedI agree with Scott in #28. There's no reason to make this process obscure. Considering that templates are static, and the content's structure/design that it reflects can be dynamic, I see having the ability to regenerate new templates with a flip of a switch as what is needed in most imaginable use cases.
On another note, I've had difficulty generating activity for a whole site (with about a couple 1000 pieces of content) with sirkitree's original process - I seem to run out of memory. So any attempt to make the process lighter would certainly be welcomed by me. I'll report back with my findings using the patch from #21.
Comment #30
Scott Reynolds commentedUsing my current patch, this won't be an issue. It uses Batch API to do it in chunks, never taking up to much memory.
Comment #31
protoplasm commentedI tested the patch in #21 and it definitely worked to regenerate comments. I also discovered I had about 35,000 comments dating back to 2005 on just one site. It took probably 15 minutes to regenerate. As much as I wanted to regenerate, I really didn't want to bloat my database by that much. So I haven't even tried the node regenerate--since there are about 10 or 20K of those. A feature that I would love to test on my site would be this regeneration feature for only the last x number days of content. I was thinking that since I set that purge value in the settings, maybe regenerate would respect that instead of regenerating all my comments back 5 years! Anyways, I had to laugh when it worked so well. Nice module. Keep up the good work. Thanks.
Comment #32
Scott Reynolds commentedThank you for the review, I'm glad it worked.
I think your right about the purge settings, though they should kick in on the next cron run. I will expore that and it might be a continuation patch. For now though, RTBC.
Comment #33
Scott Reynolds commentedok committed: http://drupal.org/cvs?commit=394472
Agreed and that was committed in this patch as well.
A lot of the cruftiness of this patch is removed in the D7 port I am working on. It is soo much cleaner: http://github.com/SupermanScott/Activity
Comment #34
Scott Reynolds commentedComment #35
jcisio commentedI've just tested and it had some token problem. My template is:
[activity-user-link] added new node [activity-node-link]Instead of using node authors, it uses the current logged user (uid 1). No problem with newly added nodes anyway.
Tested with the latest dev (Jul 29).
Comment #36
icecreamyou commentedjcisio, since the initiative that is the reason for this issue has already been committed, please open a new issue.
Comment #37
jcisio commentedIMHO the current issue is not fixed. I explained above: "No problem with newly added nodes anyway."
Comment #38
icecreamyou commentedFixed doesn't mean fixed perfectly, it just means there's a system in place to generate activity from old records. Now that that system is committed and in the repository, new problems with that system should be recorded in new issues. Besides, your problem seems not to be that the system to generate activity from old records doesn't work at all, it's that the wrong tokens are used, which is a distinct problem.
Anyway it's probably easy to fix, from a very brief look my guess is that this line needs to be added in activity/modules/node.activity.inc after line 145:
Comment #39
Scott Reynolds commentedFor those that are interested #872614: Regenerating populates the user tokens with the current users data
Comment #40
jcisio commentedWell, this is fixed elsewhere as #39