« The fallacy of free time | Main | Privacy, email and dead people »

Auto-close entries to comments and pings

It's been done by others before (Jeremy has it on his blog, mine is better cause it's longer!) but in the spirit of "not invented here" I wrote my own script which closes MT entries to comments and pings.

The idea is to cron it and forget about it and it has worked in that capacity well enough for the last few weeks.. so if anyone wants to use it (or they just like to amuse themselves by reading perl written by a Java programmer) the code is available here.

It's usage is simple and displayable with the help of the -h option, also reproduced here.

usage: mt_close_comments.pl [options]
options are
  -f                      Fake mode - don't actually do anything, just
                          provide feedback on what would have been done.
  -h                      Print usage and exit.
  -t                      Close trackbacks too.
  --days=num              Close entries older than these many days (default 15).
  --db-type=type          Type of database default is mysql
  --db-host=host          Database host  default is localhost
  --db-user=user          Database user name
  --db-pass=pass          Database password

This script closes movable type entries to comments and trackbacks with a simple
SQL query.

This is meant to be used from a cron job, sample cron entry:
# Close movable type entries that are older than 15 days to comments once a day at 4am.
#
0 4 * * * mt_close_comments.pl

TrackBack

Listed below are links to weblogs that reference Auto-close entries to comments and pings:

» Movable Type Comment And Trackback Closing Script (PHP) from Jacques Marneweck's Blog
I've hacked together a script which closes commenting and allowing trackback pings to blog entries that are older than 15 days. You can view it over here. This is a early christmas present. It was written using PHP and PEAR... [Read More]

Comments

Hey Kasia,

Just downloaded your scripts and found some wierdness.

Check this out:
./mt_close_comments.pl -f -t -days=15
Would have updated 0 entries to disallow comments.
Would have updated 0 entries to disallow trackbacks.

./mt_close_comments.pl -f -t -days=30
Would have updated 130 entries to disallow comments.
Would have updated 162 entries to disallow trackbacks.

The -t option has no effect. The days option requires only one - and -- gives the usage.

You can always tell when Perl was written by programmers who are unaccustomed to working in Perl - it's actually readable!

Fixed those, days option was a typo and -t was left with a default, thanks!

Cool Blog. But I am still a dummy in Unix.

Here's some critique and advice. Let's see how this looks when someone who *really* digs Perl does it… :-) Take it or leave it, I won't care.

First of all, and this is the biggest one: don't parse command line parameters! Use Getopt::Std or Getopt::Long. They make it simple to set up your command line interface and deal with all the common stuff like catching unknown parameters, handling a "--" to cut off your parameter list when files are being passed in, etc etc.

Secondly, along the same lines Pod::Usage lets you do *really* spiffy "--help" output. (It will show fewer or more parts of the documentation depending on verbosity requested, at the highest level it's basically a manpage built right in.)

Other notes:

I prefer to put all my functions at the top of the script so they will not be in scope of variables declared in the main program.

Calling functions with just an ampersand but no parens as in "&connect;" is a special form and makes the called function inherit the caller's @_ parameter array as its own. Don't do that unless you intended that effect.

Also, you can use "do { }" to group short parts of your code into units where declaring a sub would be overkill because the code really only appears once. It also limits the scope of variables declared inside that block and makes it clearer what parts belong together.

You should usually call "localtime" only once and calculate the bits you need from that, or you might get inconsistent results if the time happens to flip over between calls.

You're COUNT(*)ing even when -f wasn't passed. (Just by personal preference for consistence, I like always to call such a parameter -n btw — make and others set the precedent here.)

You pull in Carp, but never use it.

You can usually do better in Perl than building strings in little bits, with delimiters and spacers included in your own literals. This is particularly true when you end up doing something as ugly as chop()ping the last comma you just added to a list. Build lists and join() them insted. Also, "s///" returns the number of replacements, so you can use it directly in conditionals — "if( /foo/ ) { s/foo/bar/; ... }" is better written as "if( s/foo/bar/ ) { ... }".

DBI offers a lot of convenience methods for common cases where you just want a single-row result or such — easier than to verbosely type out the whole shebang yourself.

You don't error check every DBI call for errors, but when you do, your die()s are all over the place. Here's a tip for working with DBI: set RaiseError so anything that goes wrong will die() from within DBI, and then use "eval { }" blocks to trap exceptions in your higher level code (rather than in the bowels of your utility functions).

All that said and done, a copy of the script updated accordingly is at http://plasmasturm.org/attic/mt_close_comments

Oh, and a short note I forgot about Pod::Usage — it will rewrap your documentation for display automatically too.

I love the Getopt::Long + Pod::Usage combo. They let me add *so much* slickness to command line scripts with basically no effort at all.

Sweet, I finally have a good example of Pod documentation..


And a perlism that i've only found recently is:

my $count = () = $string =~ /stringtofind/g;

returns the number of times that item is in the string.

Why didn't you write it in Java?

Java isn't the best language for simple scripts like this. The real question you should have asked is why it took more than 5 lines. That's what it should have been.

I'm a programmer, I know the right tool for the job.

Why'd it take more than five lines?

She already explained why.

Cause it's longer? Better question is why PERL was considered a better tool for the job than PHP, Python, or even shell scripting.

Kasia - how come you use Java instead of PHP?

I hacked together a PHP version of the Movable Type comment and trackback ping closing script when I could not get the perl script to work on my server. Seeing that I use perl way too much I decided to code it in PHP and use PEAR DB for the database abstraction layer. Works like a bomb. http://www.powertrip.co.za/blog/archives/000296.html