Of all the scripting languages out there, I would have to say that Python is my favorite. I don't use it a lot, but when I need to whip up some kind of task to do some heavy text processing, or pull email down from my gMail account, I know that python can do it.
Yesterday, Ars Technica had a nice article on learning python via online resources. I was already aware of most of the references mentioned in the article, but in the comments to the article I found a gem - The Python Challenge.
The best way I can explain the Python Challenge is that it is like an adventure game with problems that can be solved using a few lines of python code. You start with problem number one, and when you have completed the problem, it will lead you to the URL for problem #2. Of course, what makes the challenge so challenging is that the problems are not always clearly spelled out on the web page. At times you'll need to view the source code and decipher clues to even find what the problem is. And then, of course, you'll need to solve the programming problem.
Right now, I am stuck on #6. I solved the programming problem, and received the ending clue ("collect the comments"), but I am not sure what to do now. I'll let it simmer in the back of my head for a while before I resort to looking for hints.
As a side note, these problems can also be solved with perl and even bash scripts. After you have completed a problem, a solution wiki page for that problem becomes available so you can see how other people solved the problem, which is always interesting and helpful.
Thursday, December 04, 2008
Thursday, November 20, 2008
Unicode and Delphi 2009
I must confess that when it comes to Unicode, I have buried my head in the sand and deliberately tried to ignore the whole transition mess from the English-centric ANSI based character set to the world-friendly Unicode standard.
To get a brief background on Unicode and what it means to developers, please see Joel's article. It is a good briefing on the problem that Unicode solves, and addresses the basics.
As mentioned in other programming related posts, my company's primary products are developed using Delphi 2007 for the Windows platform. One of the primary products is also supported on the Linux platform by using Free Pascal.
Recently, CodeGear released a new version of Delphi - 2009. Doing some research on the product, it appears as if they have made a fairly significant change to the language. In previous versions, the string type was an AnsiString, which means that one characters takes up one byte of memory. In the 2009 version, the string type is now mapped to a UnicodeString. Since a Unicode string can have one of several types of encoding which map one character to one or more bytes, it is possible that this change may drastically affect any legacy Delphi application which processes strings, especially if it is a library which is used by other applications.
Thankfully, CodeGear has provided developers with three articles {part 1, part 2, part 3} detailing the changes made, and gotchas to look out for when porting legacy applications over to Delphi 2009. Please take a look at these articles to see what the potential obstacles are when moving your applications over, and consider the difficulties. Third party components will most likely also need to be tweaked to work with Delphi 2009, so keep that in mind as well. You can find PBear's HTML viewer updated for Delphi 2009 here, along with other free components.
As far as Free Pascal is concerned, Unicode support and compatibility is something that they are currently hashing through. Until a Delphi 2009 Unicode compatibility mode can be implemented in Free Pascal, we will be forced to stick with Delphi 2007 for the time being.
To get a brief background on Unicode and what it means to developers, please see Joel's article. It is a good briefing on the problem that Unicode solves, and addresses the basics.
As mentioned in other programming related posts, my company's primary products are developed using Delphi 2007 for the Windows platform. One of the primary products is also supported on the Linux platform by using Free Pascal.
Recently, CodeGear released a new version of Delphi - 2009. Doing some research on the product, it appears as if they have made a fairly significant change to the language. In previous versions, the string type was an AnsiString, which means that one characters takes up one byte of memory. In the 2009 version, the string type is now mapped to a UnicodeString. Since a Unicode string can have one of several types of encoding which map one character to one or more bytes, it is possible that this change may drastically affect any legacy Delphi application which processes strings, especially if it is a library which is used by other applications.
Thankfully, CodeGear has provided developers with three articles {part 1, part 2, part 3} detailing the changes made, and gotchas to look out for when porting legacy applications over to Delphi 2009. Please take a look at these articles to see what the potential obstacles are when moving your applications over, and consider the difficulties. Third party components will most likely also need to be tweaked to work with Delphi 2009, so keep that in mind as well. You can find PBear's HTML viewer updated for Delphi 2009 here, along with other free components.
As far as Free Pascal is concerned, Unicode support and compatibility is something that they are currently hashing through. Until a Delphi 2009 Unicode compatibility mode can be implemented in Free Pascal, we will be forced to stick with Delphi 2007 for the time being.
Tuesday, November 11, 2008
Wednesday, August 20, 2008
Calf Muscle Rehabilitation and Soccer
It has been just over one year since my last calf muscle injury. The blog post I made on the subject is the #1 post for my humble blog, as it pops up as a search result thanks to Google. As regular readers (I have at least 2) may know, I surf quite a bit - working 5 minutes away from the beach lets me use my lunch hour to get some water time in.
While I love surfing, it doesn't do much to stretch out or strengthen my lower body (however, it is very good for the upper body). So, I decided to look around for an adult soccer league to join that would be good exercise for my legs. Luckily, I found a men's over-35 team in Carlsbad that needed a few players, so I signed up.
About 2 weeks ago, I suited up in shin guards and cleats, and went down to a local field to try and get my feet on the ball a bit. I have coached youth soccer for the last 4 years, and look forward to actually playing again.
You can probably guess what happened next... After a workout on Tuesday, my right lower calf muscle felt a little tweaked, but not too bad - just a bit uncomfortable. On Thursday, I laced up and went to jog across the field and back to warm up a bit before stretching, and on the return leg the tweak cranked up a lot, and I had to stop and limp back.
It didn't feel like my previous two incidents, so I think that I did not tear the muscle - maybe just strained it or something like that. I limped for about 24 hours, and then started looking at how to stretch out the calf muscles to try and prevent this in the future.
I have stretched in the past, but I have never focused on the calf muscles. Instead, I'd work the quads, hammys, and groin. I realized that I had been neglecting my calves - pretty stupid of me (especially after two injuries).
Maybe neglecting is the wrong word... I have never been shown how to stretch out the calf, in all the sports I have played and gym classes taken through school and even in college. So, with the theory of "knowing your enemy" in mind, I first did some reading up on the calf muscle, which is actually a pair of muscles: the gastrocnemius and soleus. The article even mentions torn calf muscles, the 'pop' that so many of us feel, and the conditions that triggered it in my cases: sudden acceleration and changes in direction.
Next, I did a search on stretches focusing on the pair of calf muscles, and found these: gastrocnemius stretch and soleus stretch. Since I found these videos, I've been doing both stretches for 90 seconds on each leg, and I do believe that my lower legs are feeling better. I'm not back to 100% yet, but I can make my way around the pitch if I take care to avoid sudden acceleration and changes in direction. I hope to be back up to 95% before the first game of our season, which starts on September 5th.
If you have hurt your calf, please be careful to not stretch it out prematurely. A bad tear can take a long time to heal, so when you start trying to stretch, let common sense be your guide. Stretch slowly and gently, avoiding bouncing. Any pain should be a sign that you are doing too much too fast.
To keep the rest of your lower body in shape, I found that biking was fairly low impact for my most recent injury, so long as I didn't stand up and pedal (pushing on the front portion of the foot as you do to begin a sprint).
If you know of any other good stretches, or want to talk about your calf injury, please feel free to comment below!
While I love surfing, it doesn't do much to stretch out or strengthen my lower body (however, it is very good for the upper body). So, I decided to look around for an adult soccer league to join that would be good exercise for my legs. Luckily, I found a men's over-35 team in Carlsbad that needed a few players, so I signed up.
About 2 weeks ago, I suited up in shin guards and cleats, and went down to a local field to try and get my feet on the ball a bit. I have coached youth soccer for the last 4 years, and look forward to actually playing again.
You can probably guess what happened next... After a workout on Tuesday, my right lower calf muscle felt a little tweaked, but not too bad - just a bit uncomfortable. On Thursday, I laced up and went to jog across the field and back to warm up a bit before stretching, and on the return leg the tweak cranked up a lot, and I had to stop and limp back.
It didn't feel like my previous two incidents, so I think that I did not tear the muscle - maybe just strained it or something like that. I limped for about 24 hours, and then started looking at how to stretch out the calf muscles to try and prevent this in the future.
I have stretched in the past, but I have never focused on the calf muscles. Instead, I'd work the quads, hammys, and groin. I realized that I had been neglecting my calves - pretty stupid of me (especially after two injuries).
Maybe neglecting is the wrong word... I have never been shown how to stretch out the calf, in all the sports I have played and gym classes taken through school and even in college. So, with the theory of "knowing your enemy" in mind, I first did some reading up on the calf muscle, which is actually a pair of muscles: the gastrocnemius and soleus. The article even mentions torn calf muscles, the 'pop' that so many of us feel, and the conditions that triggered it in my cases: sudden acceleration and changes in direction.
Next, I did a search on stretches focusing on the pair of calf muscles, and found these: gastrocnemius stretch and soleus stretch. Since I found these videos, I've been doing both stretches for 90 seconds on each leg, and I do believe that my lower legs are feeling better. I'm not back to 100% yet, but I can make my way around the pitch if I take care to avoid sudden acceleration and changes in direction. I hope to be back up to 95% before the first game of our season, which starts on September 5th.
If you have hurt your calf, please be careful to not stretch it out prematurely. A bad tear can take a long time to heal, so when you start trying to stretch, let common sense be your guide. Stretch slowly and gently, avoiding bouncing. Any pain should be a sign that you are doing too much too fast.
To keep the rest of your lower body in shape, I found that biking was fairly low impact for my most recent injury, so long as I didn't stand up and pedal (pushing on the front portion of the foot as you do to begin a sprint).
If you know of any other good stretches, or want to talk about your calf injury, please feel free to comment below!
Thursday, August 14, 2008
Trip to Italy - Part 3
The final destination of our grand Italian vacation was the beautiful city of Venice. They say that the farther you go North in Italy, the more expensive it gets. From our limited experience (from Naples in the southern portion of the country, to Rome in the middle, and then Venice in the North), I can indeed confirm this piece of folk wisdom.
Venice is a tourist destination for a large number of people from Europe and Asia. The city seemed much more ritzy-touristy than Rome, which had many historical sites. Venice, on the other hand, features a large number of ways to separate you from your money via high-end shops and restaurants.
The municipal coat of arms for Venice features a winged lion, and you see this symbol throughout Venice. I can hardly think of a better mascot, short of Trogdor the Burninator.
We walked through the open air market near the Rialto Bridge one morning, and saw some of the local produce and seafood, which is boated in daily.
The architecture of Venice fascinated me the most. It is a city with almost no land unused. The alleyways twist and wind through the buildings, occasionally meeting in a small plaza or crossing a canal. The lesser traveled walkways (sometimes only 3 or 4 people wide) can be eerily quiet even in the middle of the day, and it is always interesting to see what shops are found on these lesser traveled routes.
After three days in Venice and 10 days in Italy, we had to make our way back home. It was a great vacation with the family, and something I think we will all remember for the rest of our lives.
Venice's Grand Canal
Venice is a tourist destination for a large number of people from Europe and Asia. The city seemed much more ritzy-touristy than Rome, which had many historical sites. Venice, on the other hand, features a large number of ways to separate you from your money via high-end shops and restaurants.
Dining al Fresco
The municipal coat of arms for Venice features a winged lion, and you see this symbol throughout Venice. I can hardly think of a better mascot, short of Trogdor the Burninator.
We walked through the open air market near the Rialto Bridge one morning, and saw some of the local produce and seafood, which is boated in daily.
Local Produce
Fresh Seafood
The architecture of Venice fascinated me the most. It is a city with almost no land unused. The alleyways twist and wind through the buildings, occasionally meeting in a small plaza or crossing a canal. The lesser traveled walkways (sometimes only 3 or 4 people wide) can be eerily quiet even in the middle of the day, and it is always interesting to see what shops are found on these lesser traveled routes.
Horse - the other red meat!
After three days in Venice and 10 days in Italy, we had to make our way back home. It was a great vacation with the family, and something I think we will all remember for the rest of our lives.
Wednesday, August 06, 2008
Trip to Italy - Part 2
While we stayed in Rome for the week, we made two day trips during those 7 days. Our first day trip (by way of a very comfortable high speed train) was to Florence. We had reservations to the Accademia dell'Arte del Disegno to see Michelangelo's David and several other works of art (sorry, no cameras allowed!).
We then walked about the city, taking in the sights and sounds. A bus tour sped us through the highlights of the locale, and we visited the Ponte Vecchio ("old bridge"). The Ponte Vecchio was first constructed by the Romans, and was the only bridge not destroyed by the German forces during their withdrawl from Italy in 1944, allegedly because of an express order by Hitler.
Our second day trip took us South of Rome, to Naples. From Naples we caught a local train to Pompeii. What can I say about Pompeii, other than it was truly an amazing experience? It boggles my mind how complete a city it was, nearly 2000 years ago!
The city is so well preserved that some of the artwork (mostly frescos) is still visible, and quite beautiful.
We spent a good 5 hours walking around Pompeii, and could have easily extended that to a full day if we had the time. Herculaneum is Pompeii's lesser known sister city, which faced a similar fate. That archeological site would have needed another day in and of itself as well.
We then made our way back to Naples, and had pizza Margherita at pizzeria “Da Michele” - supposedly the place which originated this style of pizza. I can't say too much positive about the city of Naples itself (other than the pizza), as it was still recovering from a trash workers strike. We had to be extra careful of pick-pockets and others, and that extra vigilance can take a toll on your ability to relax and enjoy the sights and sounds.
My next post will cover our three days in Venice!
Fountain in Florence
We then walked about the city, taking in the sights and sounds. A bus tour sped us through the highlights of the locale, and we visited the Ponte Vecchio ("old bridge"). The Ponte Vecchio was first constructed by the Romans, and was the only bridge not destroyed by the German forces during their withdrawl from Italy in 1944, allegedly because of an express order by Hitler.
Our second day trip took us South of Rome, to Naples. From Naples we caught a local train to Pompeii. What can I say about Pompeii, other than it was truly an amazing experience? It boggles my mind how complete a city it was, nearly 2000 years ago!
Pompeii Baking Area
The city is so well preserved that some of the artwork (mostly frescos) is still visible, and quite beautiful.
Fresco on the wall of a Pompeii house
We spent a good 5 hours walking around Pompeii, and could have easily extended that to a full day if we had the time. Herculaneum is Pompeii's lesser known sister city, which faced a similar fate. That archeological site would have needed another day in and of itself as well.
Vesuvius and Family
We then made our way back to Naples, and had pizza Margherita at pizzeria “Da Michele” - supposedly the place which originated this style of pizza. I can't say too much positive about the city of Naples itself (other than the pizza), as it was still recovering from a trash workers strike. We had to be extra careful of pick-pockets and others, and that extra vigilance can take a toll on your ability to relax and enjoy the sights and sounds.
My next post will cover our three days in Venice!
Wednesday, May 21, 2008
Trip to Italy - Part 1
Well, things have been very busy for me and my family, but I have a few spare minutes and thought that I would update the blog on our biggest event this year so far - our trip to Italy. We went with our extended family, and everyone had a great time.
Several months before leaving, I decided to try and pick up as much of the Italian language as possible. I purchased a few books, and even gave the (very boring) Rosetta Stone program a try. However, the best tool I found for picking up conversational Italian is Pimsleur's Speak and Read Italian.
There are three courses in the series, each consisting of 30 lessons. Each lesson is just under 30 minutes, which just so happens to perfectly coincide with my commute time. Thus, I would often listen to a lesson on the way to work, and then repeat it on the way home or advance to the next one. I made good progress through the lessons, and made it half way through the Italian II course before we headed off to Italy.
We left for Italy on the Saturday before Easter, and actually arrived in Rome Easter morning. We spent that day checking into our hotel, relaxing, and trying to get a feel for the new surroundings.
There are a lot of sights to see in Rome, as one might expect of a city with over 2,700 years of history. We took a bus tour around The Eternal City to get a feel for it, and stopped off at Piazza Navona to walk around a bit.
A short walk from there, and you'll find yourself at the Pantheon.
There are many fountains throughout Rome, built to bring water to the people. The water is fresh and we drank it often during our walks through Rome.
My youngest son thought that the Colosseum was extremely impressive, and I would have to agree. Although parts of it were cannibalized for construction later on in Rome's history, a good portion of it still stands today. Perhaps most impressive were the storage areas underneath the main "floor", where the gladiators and animals they fought were kept. You can see today where elevators raised new and exciting beasts to the arena floor.
Exploring the forum and the ruins around it are definitely worth your time. Don't miss out on hiking up Palatine Hill to get a breathtaking view of Rome, and stroll through the Emperor's palace.
My next post will cover two of our days trips from Rome...
Several months before leaving, I decided to try and pick up as much of the Italian language as possible. I purchased a few books, and even gave the (very boring) Rosetta Stone program a try. However, the best tool I found for picking up conversational Italian is Pimsleur's Speak and Read Italian.
There are three courses in the series, each consisting of 30 lessons. Each lesson is just under 30 minutes, which just so happens to perfectly coincide with my commute time. Thus, I would often listen to a lesson on the way to work, and then repeat it on the way home or advance to the next one. I made good progress through the lessons, and made it half way through the Italian II course before we headed off to Italy.
We left for Italy on the Saturday before Easter, and actually arrived in Rome Easter morning. We spent that day checking into our hotel, relaxing, and trying to get a feel for the new surroundings.
View from Our Room
There are a lot of sights to see in Rome, as one might expect of a city with over 2,700 years of history. We took a bus tour around The Eternal City to get a feel for it, and stopped off at Piazza Navona to walk around a bit.
Piazza Navona
A short walk from there, and you'll find yourself at the Pantheon.
Pantheon
There are many fountains throughout Rome, built to bring water to the people. The water is fresh and we drank it often during our walks through Rome.
Trevi Fountain
My youngest son thought that the Colosseum was extremely impressive, and I would have to agree. Although parts of it were cannibalized for construction later on in Rome's history, a good portion of it still stands today. Perhaps most impressive were the storage areas underneath the main "floor", where the gladiators and animals they fought were kept. You can see today where elevators raised new and exciting beasts to the arena floor.
Colosseum
Exploring the forum and the ruins around it are definitely worth your time. Don't miss out on hiking up Palatine Hill to get a breathtaking view of Rome, and stroll through the Emperor's palace.
Family
My next post will cover two of our days trips from Rome...
Wednesday, April 09, 2008
Rest In Peace, Ace
Ace, our dog of almost 13 years, was laid to rest on Friday March 21st, 2008. He leaves behind a family that misses him terribly.
I've mentioned Ace in several of my posts, and if you have ever been to my house over the last 13 years, you have certainly met him. He was a large and friendly dog that my wife and I picked out from the local animal shelter approximately one year before our first child was born. It turns out that his other siblings were not able to be adopted, as all of them were sick. We were lucky that we picked him out of the litter before the vet had a chance to look at him.
During the early years of his life, he provided my wife with both companionship and security as our children were born. She wasn't ever worried about being home alone while I was at work, so long as Ace was around. Later on, he was a friend and protector of our children.
During his last year of life, we saw his health steadily decline. His hearing deteriorated quite a bit, and his bouts of nervousness increased. Near the end, he had an eye infection in his left eye that he just couldn't seem to shake off, despite medication. His appetite was a mere fraction of what it used to be. Finally, he lost his footing with his rear legs and hips, and went to the floor. After attempting to get him up and mobile that day, and after several trips to the vet over the previous two weeks, my wife and I decided that it was time to let Ace go.
I have never owned a dog from puppyhood through death, so taking him to the vet on his last day was a new experience for me, and for my kids. The vet and techs were very understanding and helpful. It took four of them to get Ace out of the car and onto a stretcher, such was his lack of mobility. He never made a peep, and seemed content and ready.
After we said our goodbyes to him, I held him as they injected him with the sedatives that would release him. I can only hope he understood how much all of us loved him.
The old cliche goes, "you don't know what you've got until it's gone". I find myself "seeing" him out of the corner of my eye sometimes, only to realize upon further inspection that it was a blanket or shadow. I have to battle to not leave the back door open for him, and still expect to see him first when I come home from work in the afternoon (he was always the first to greet me). I miss his company in the mornings when only he and I were awake in the house as I prepared for work.
Rest in peace, Ace. We love you, and you will never be forgotten.
Tuesday, March 18, 2008
Now Using Greylite
In this old post, I spilled the beans on my new and improved spam filtering triple play: dspam, qgreylist and RBL checking. Overall, the system has worked well over the last four months, though I have noticed the increasing volume of spam showing up in my spam folder.
I suspected that the very simple form of greylisting implemented in qgreylist was the culprit, and after a bit of investigation, I found out that this indeed was the case. So, I set out to see if there was another greylisting implementation which could be used in my qmail installation.
Using my google-fu, I quickly zeroed in on Greylite. After reading up on it, I found that it held several advantages over qgreylist:
Less than 5 mintues later, and the server was up and running with its new greylisting implementation up and working perfectly. Flawless victory!
I suspected that the very simple form of greylisting implemented in qgreylist was the culprit, and after a bit of investigation, I found out that this indeed was the case. So, I set out to see if there was another greylisting implementation which could be used in my qmail installation.
Using my google-fu, I quickly zeroed in on Greylite. After reading up on it, I found that it held several advantages over qgreylist:
- Written in C instead of perl, so it should perform a bit snappier and be less of a burden on the mail server.
- Instead of only considering the IP address of the sender as qgreylist does, greylite considers the complete triplet of {IP address, from, to} before validating an IP address.
- All data is stored in a single sqlite3 database, whereas qgreylist stored the verified IP addresses as files in a single directory, which clutters the filesystem and increases access time in that directory as more IPs are validated.
- Greylite appears to have some enhanced functionality called `tuning suspicion' which allows you to customize how it behaves in certain circumstances.
Less than 5 mintues later, and the server was up and running with its new greylisting implementation up and working perfectly. Flawless victory!
Thursday, March 13, 2008
Baseball Season Update
So, here we are over two weeks into our little league baseball season - how is our team doing? Well, we have 0 wins and 4 losses, so one could make the argument that we are not doing too well. I would have to agree.
The kids seem to be having a good time, however. So long as they continue to enjoy the game and improve over the course of the season, I'll be content. Wish us luck!
The kids seem to be having a good time, however. So long as they continue to enjoy the game and improve over the course of the season, I'll be content. Wish us luck!
Tuesday, February 26, 2008
By Request - My dspam Training Script
In a post I made about one year ago, I mentioned a script which I created which trains dspam to recognize missed spam email, and corrects it when it falsely identifies a good ( or "ham") email as spam. Someone has requested that I post that script, so here it is. Please note that my qmail installation uses the maildir format!
--- start file: train-spam.sh ---
#!/bin/sh
# train-spam.sh
#
# Description: Checks each user's /home/Maildir/.Spam.Missed
# directories to see if the user placed any "missed" spam
# messages which got through SpamAssassin to their INBOX.
# If there are messages in this directory, then the script
# invokes sa-learn to update the site-wide tokens to try
# and improve the defenses for next time...
#
# learn_spam - Function which takes a directory and a user as
# arguments, and then feeds that directory to our anti-spam
# applications for further SPAM training.
#
# Arguments:
# $1 - Directory name containing SPAM emails. Required
# $2 - User name. If it is not provided, $USER will be used.
#
# Example:
# learn_spam /home/alank/Maildir/.Spam.Missed/cur alank
#
function learn_spam {
# loop through all emails in given directory
for email in $(ls $1); do
# process SPAM email using DSPAM
/usr/local/bin/dspam --mode=teft --source=error --class=spam --feature=chained,noise --user $2 < $1/$email
echo -n "."
# delete SPAM email
rm $1/$email
done # end of email loop
} # end function learn_spam
# learn_ham - Function which takes a directory and a user as
# arguments, and then feeds that directory to our anti-spam
# applications for further HAM training.
#
# Arguments:
# $1 - Directory name containing HAM emails. Required
# $2 - User name. If it is not provided, $USER will be used.
#
# Example:
# learn_ham /home/alank/Maildir/.Spam.NotSpam/cur alank
#
function learn_ham {
# loop through all emails in given directory
for email in $(ls $1); do
# process HAM email using DSPAM
/usr/local/bin/dspam --mode=teft --source=error --class=innocent --feature=chained,noise --user $2 < $1/$email
echo -n "."
# delete HAM
rm $1/$email
done # end of email loop
} # end function learn_ham
#
# Script starts here!
#
# loop through all user home directories
for file in $(ls /home); do
# if there is a Spam/Missed maildir
if [ -d /home/$file/Maildir/.Spam.Missed/cur ]; then
# then process any missed SPAM
echo -n "missed spam for $file: "
learn_spam /home/$file/Maildir/.Spam.Missed/cur $file
learn_spam /home/$file/Maildir/.Spam.Missed/new $file
echo ""
fi # end if
# if there is a Spam/NotSpam dir
if [ -d /home/$file/Maildir/.Spam.NotSpam/cur ]; then
# then process any falsely identified spam, i.e. HAM
echo -n "false positives for $file: "
learn_ham /home/$file/Maildir/.Spam.NotSpam/cur $file
learn_ham /home/$file/Maildir/.Spam.NotSpam/new $file
echo ""
fi # end if
done # end for loop
echo "Done!"
--- end file: train-spam.sh ---
I place the above script in /root and create a cron job to run it every day in the early morning. You will need to edit some parts of the script if your missed spam and not spam directories are named differently. Good luck, and I hope it is helpful in your continuing battle against spam!
--- start file: train-spam.sh ---
#!/bin/sh
# train-spam.sh
#
# Description: Checks each user's /home/Maildir/.Spam.Missed
# directories to see if the user placed any "missed" spam
# messages which got through SpamAssassin to their INBOX.
# If there are messages in this directory, then the script
# invokes sa-learn to update the site-wide tokens to try
# and improve the defenses for next time...
#
# learn_spam - Function which takes a directory and a user as
# arguments, and then feeds that directory to our anti-spam
# applications for further SPAM training.
#
# Arguments:
# $1 - Directory name containing SPAM emails. Required
# $2 - User name. If it is not provided, $USER will be used.
#
# Example:
# learn_spam /home/alank/Maildir/.Spam.Missed/cur alank
#
function learn_spam {
# loop through all emails in given directory
for email in $(ls $1); do
# process SPAM email using DSPAM
/usr/local/bin/dspam --mode=teft --source=error --class=spam --feature=chained,noise --user $2 < $1/$email
echo -n "."
# delete SPAM email
rm $1/$email
done # end of email loop
} # end function learn_spam
# learn_ham - Function which takes a directory and a user as
# arguments, and then feeds that directory to our anti-spam
# applications for further HAM training.
#
# Arguments:
# $1 - Directory name containing HAM emails. Required
# $2 - User name. If it is not provided, $USER will be used.
#
# Example:
# learn_ham /home/alank/Maildir/.Spam.NotSpam/cur alank
#
function learn_ham {
# loop through all emails in given directory
for email in $(ls $1); do
# process HAM email using DSPAM
/usr/local/bin/dspam --mode=teft --source=error --class=innocent --feature=chained,noise --user $2 < $1/$email
echo -n "."
# delete HAM
rm $1/$email
done # end of email loop
} # end function learn_ham
#
# Script starts here!
#
# loop through all user home directories
for file in $(ls /home); do
# if there is a Spam/Missed maildir
if [ -d /home/$file/Maildir/.Spam.Missed/cur ]; then
# then process any missed SPAM
echo -n "missed spam for $file: "
learn_spam /home/$file/Maildir/.Spam.Missed/cur $file
learn_spam /home/$file/Maildir/.Spam.Missed/new $file
echo ""
fi # end if
# if there is a Spam/NotSpam dir
if [ -d /home/$file/Maildir/.Spam.NotSpam/cur ]; then
# then process any falsely identified spam, i.e. HAM
echo -n "false positives for $file: "
learn_ham /home/$file/Maildir/.Spam.NotSpam/cur $file
learn_ham /home/$file/Maildir/.Spam.NotSpam/new $file
echo ""
fi # end if
done # end for loop
echo "Done!"
--- end file: train-spam.sh ---
I place the above script in /root and create a cron job to run it every day in the early morning. You will need to edit some parts of the script if your missed spam and not spam directories are named differently. Good luck, and I hope it is helpful in your continuing battle against spam!
Yes, I Am Still Here
Wow - it's a little dusty around here, isn't it? I haven't updated the ole' blog in months, and every time I did think about updating it, I said to myself, "but it's been so long!" That is a nice self-perpetuating situation, so now it's time I break free from the shackles of stupidity and update the damn thing.
I am very well aware that I still need to post pictures up from last summer's vacation, but those will have to wait for another day. Instead, I'll try to catch you up with what has happened over the last four months or so.
Little League
As I may have mentioned previously, I am on the board of directors for our local little league. Finding volunteers is always a challenge, as many people are just too busy (or unable) to help out. I have managed my son's team for the last three years, and really enjoyed it and the kids and parents in the community that I have been lucky enough to meet and get to know. Since the league was in dire straits to find a new board, I volunteered as the information officer.
It has been a lot of work, but overall, I think it is worth it. The people on the board are all good people, doing their best to make sure that the kids of our community have the opportunity to baseball in a safe and fun environment. I have spent late nights at monthly board meetings, weekends doing sign-ups and field prep work, and time during the day responding to board emails and the like.
I am not managing this year, and am instead, merely coaching. It's sort of driving me nuts not being in control, but I'll get over it.
Christmas
I took my normal two weeks off after Christmas, and promptly got sicker than I was all year. During the coarse of 2008, I took two sick days off from work. While on vacation, I was bed ridden for nearly three days. That'll teach me...
Other than that, we had a very nice Christmas and New Years. No Christmas cards were sent this year, due to the ebola plague that swept through the house. I like to think of it as a minor inconvenience to our friends, and a minor bonus for the tress.
Tech-talk
The day after Thanksgiving, I braved Fry's and purchased parts for a new computer at prices almost too good to be true. Actually, they were too good to be true because of those damn rebates. Here it is, four months later, and I am still waiting on my final rebate to arrive from Abit.
The system is an Intel Core Duo 2.6 Ghz machine with 2 GB ram, and nice Nvidia video card, and a decent SATA hard drive. It plays Team Fortress 2 beautifully, and I haven't really bought any other recent games due to time limitations. It should last me for the next couple of years easily.
So, that is a very brief update of what I've been doing over these last few months. I'll try to update the blog a bit more regularly as time and obligations permit.
Subscribe to:
Posts (Atom)