Automate reporting spam to spamcop.net

February 6th, 2012

Reporting spam to SpamCop can get to be tiresome. The normal process is:

Receive spam Copy the raw message Log into SpamCop.net Paste the message Wait for the verification message Mark the message as spam in Mail Delete the message Click the link in the verification message Wait for spamcop.net’s nag screen to go away Submit the spam report Delete the verification message from Mail

Luckily much of it can be automated with Mac Mail and some AppleScripting. The solution I’m posting boils it down to:

1. Receive spam
2. Fire a script via the applescript menu
9. Wait for SpamCop.net’s nag screen to go away
10. Submit the spam report

As you can see, 7 steps are handled automatically.

Instructions

The first thing you have to do is grab the scripts from github: SpamCop Deputy

Next set up an account at SpamCop.net. When you log in, set the expiration to 1 year.

Enable the AppleScript menu.

1) Open “AppleScript Editor.app”. It will either be in your Applications folder or Utilities folder.
2) Edit General preferences, and turn on “Show Script menu un menu bar”.
Now you’ll have an easy way to fire off the initial script. These items are only available when Mail is the front most application.

Set up a script to send SpamCop the raw source of the spam messages.

1) Create this folder if it does not exist: ~/Library/Scripts/Applications/Mail
2) Drop the attached “SpamCopNotify.scpt” into that folder.
3) Edit line 1 with your unique SpamCop email submission address.
This script will get the raw source of all messages selected in Mail and send them to SpamCop, mark the message as read, mark the message as spam, then delete the message.

Set up a script to handle the SpamCop verification email.

1) Drop the attached “SpamCopIn.scpt” file into the same folder as the previous script.
This script will automatically ‘click’ the verification link and delete the verification email.

Add a mail rule to fire SpamCopIn.scpt when the verification email is received.

1) Create a new mail rule
2) If all of the following are met:
+ Received is less than 2 days old (that’s a spamcop rule)
+ From contains “spamcop@devnull.spamcop.net”
+ Message content contains “http://www.spamcop.net/sc?id=”
3) Perform the following actions:
+ Run AppleScript “~/Library/Scripts/Applications/Mail/SpamCopIn.scpt”
+ Play Sound [any] (this is optional)
4) Do Not Apply when prompted to do so when you save.

Now we’re all ready to go.

Next time you get spam…
1) Select the message(s)
2) From the AppleScript menu, select “SpamCopNotify.scpt”
SpamCopNotify.scpt will get the raw source of all messages selected in Mail and send them to SpamCop.
The messages will be marked as read, marked as spam then deleted.
SpamCop will reply with a verification message(s) shortly.
Mail will evaluate the verification message(s) with it’s rules and launch the SpamCopIn.scpt script.
SpamCopIn.scpt will find the verification link and launch it in your default browser as a new window/tab.
The message will be marked as read then deleted.
3) When your browser opens the SpamCop site, wait for the nag screen to go away then press “Process Spam”.

Mac OS X, SpamCop Deputy AppleScript, github, mail.app, spam, spamcop

Trimming a decimal with coldfusion & regex

January 12th, 2012

Today I had to import lots of measurements into a mySql table. The columns allow 3 places after the decimal. The data has mixed precision – some values use all 3 places, others use none. To make the output look clean I didn’t want to show all 3 places all the time. So numberFormat() was out. And unlike PHP, coldFusion’s trim() function does not take any parameters (trim trailing zeros and periods). I came up with using two regular expressions to remove any trailing zeros, then the trailing period if any.

Here is some example data:

6.000 0.375 0.500

When using numberFormat(), the output is:

6 0 1

… and numberFormat(val, 0.000) gives:

6.000 0.375 0.500

Blech. So here’s the function that gave exactly what I wanted:

<cffunction name="trimDecimal">
 <cfargument name="value">
 <cfreturn REReplace(REReplace(value, "0+$", "", "ALL"), "\.+$", "")>
</cffunction>

… trimDecimal(val) resulting in…

6 0.375 0.5

Perfect.

ColdFusion decimals, RegEx, ReReplace

Return a query of all CF Scheduled tasks

September 27th, 2011

I was working on a scheduled task in a shared hosting environment. Which is pretty frustrating when you don’t have access to the CF Administrator.

Googling, I found some functions that would return information about scheduled tasks via coldfusion.server.ServiceFactory. That of course would not work since shared hosting environments have that locked down.

Then I came across an old post by Ben Forte. Instead of ServiceFactory he used an undocumented task called ‘__list’. It almost worked… except that it errored out on some task attributes. I guess a mismatch in versions of CF is to blame.

So I took that undocumented call, then rebuilt the rest entirely. I basically turned the data into tab-separated-values. I haven’t gotten around to learning reFind(), etc yet so please excuse the many replace() functions. It’s very low tech, but it works.

It won’t matter if you expect extra column names than __list gives (those columns in the returned query will be [empty string]s). And it also won’t matter if __list gives more than you’ve expected (those extra columns won’t be in the returned query). In either case, there will be no errors.

<cffunction
        name="getCFScheduledTasks"
        returntype="query"
        output="no"
        hint="Returns a query of CF Scheduled tasks on the server"
>
<!---
Thanks to Ben Forte for posting the undocumented call '__list'
--->
        <cfsavecontent variable='tasks'>
            <cfschedule action='run' task='__list'>
        </cfsavecontent>

        <!--- TRIM WHITESPACE --->
        <cfset tasks = trim(tasks)>
        <cfset tasks = replace(tasks, chr(10), '', 'all')>

        <!--- REMOVE FIRST AND LAST BRACKETS --->
        <cfset tasks = mid(tasks, 2, len(tasks)-3)>

        <!--- CHANGE THE TASK DELIMETER --->
        <cfset tasks = replace(tasks, '}}},', '}}#chr(10)#', 'all')>

        <!--- CHANGE THE COLUMN DELIMETERS --->
        <cfset tasks = replace(tasks, '={{', chr(9), 'all')>
        <cfset tasks = replace(tasks, '},', '}#chr(9)#', 'all')>

        <!--- REMOVE THE ROW TRAILING BRACKETS --->
        <cfset tasks = replace(tasks&chr(10), '}}#chr(10)#', '}#chr(10)#', 'all')>

        <!--- REMOVE THE COLUMN TRAILING BRACKETS --->
        <cfset tasks = replace(tasks, '}#chr(9)#', chr(9), 'all')>

        <!--- TASK DATA COLUMNS --->
        <cfset columns = 'task,start_date,start_time,last_run,end_time,interval,operation,url,resolveurl,request_time_out,username,password,http_port,path,proxy_server,http_proxy_port,file,disabled,paused,publish'>

        <!--- CREATE A QUERY --->
        <cfset cfScheduledTasks=QueryNew(columns)>

        <!--- LOOP OVER THE ROWS & COLUMNS, ADDING TO THE QUERY --->
        <cfloop list="#tasks#" delimiters="#chr(10)#" index="row">
                <cfset QueryAddRow(cfScheduledTasks)>
                <cfloop list="#columns#" index="column">
                        <cfloop list="#row#" delimiters="#chr(9)#" index="data">
                                <cfif spanExcluding(data, '=') eq column>
                                        <cfset QuerySetCell(cfScheduledTasks, column, replace(data, column&'={', ''))>
                                </cfif>
                        </cfloop>
                </cfloop>
        </cfloop>

        <!--- WWWEEEE! --->
        <cfreturn cfScheduledTasks>
</cffunction>

<cfset cfScheduledTasks = getCFScheduledTasks()>
<cfdump var='#cfScheduledTasks#'>

Ben's original code is at: http://www.forta.com/blog/index.cfm/2006/8/28/GetScheduledTasks-Function-Returns-Scheduled-Task-List

ColdFusion cffunction, scheduled tasks, shared hosting

MySQL: Ignore null values when ordering results

August 22nd, 2011

Fast answer: use IFNULL() in your select statement.

Lets say you have some products that have a length attribute which is recorded in two different ways: inches and feet. In your CMS, the client enters EITHER inches OR feet. When generating a list of products sorted by length, you’d want the ‘inch’ products up top and the ‘feet’ products under them. At first, you’d probably try this:

SELECT id, title, lenIN, lenFT
FROM products
ORDER BY lenIN, lenFT

But that would give you the ‘feet’ products first since the inch values would be null. A second attempt:

SELECT id, title, lenIN, lenFT
FROM products
ORDER BY lenIN DESC, lenFT

That of course puts the products in the wrong ordering. Here is the fix:

SELECT id, title, IFNULL(lenIN, 1000) as tempIN, lenIN, lenFT
FROM products
ORDER BY tempIN, lenIN, lenFT

It comes from the magic of:

IFNULL(expr1,expr2)

If expr1 is not NULL, IFNULL() returns expr1, else it returns expr2. So when inches is null, a value of 1000 is used. I picked ‘1000′ because I’m sure no product will be 1000 inches long (feet would surely be used at that point). The result is the product which have inches filled will be put at the top of the list, ordered correctly, followed by the products where inches were blank (and are now 1000 inches).

MySQL

Change the priority of incoming mail (incl. Apple Mail)

February 4th, 2011

… or, ‘the sender that cried emergency’.

Before I get into this article I’d first like to point out that this solution was not born out of anger, hostility, or any other negative vibe. It’s simply a usability and project management issue.

The Problem

We probably all have a sender or two that abuse the Priority setting of email messages. Perhaps they honestly think many of their message are actually very important. And that’s fine, priority can be objective. But it does cause a problem when checking email.

Just like The Boy Who Cried Wolf, a sender that sets too many messages to High Priority runs the risk of being ignored. That certainly is not good for the sender. When other senders don’t use the priority setting, those messages get deferred. Not necessarily a good thing either. Turning off the Priority column to cut down the noise makes legitimately important messages look normal priority. Turning off the Priority column to cut down the noise also gets rid of the ‘Flagged’ designation.

So basically speaking, someone who abuses the priority setting can really muck up the works. And you can’t really them about it either.

Some email programs let you change the priority of incoming mail. I use Apple’s Mail as a mail client and it does not. I checked out scripts, plugins, even a workaround of moving the message to the Drafts mbox, change the priority, then move it back to the in mbox… which is not good because then it sets you as the sender. D’oh! I also tried editing the emlx file on the hard drive but that didn’t work, I guess because I’m using IMAP. What then can we do?

The Fix

What we need to do is target those few senders, reset the priority of their incoming messages, and add a visual clue that it was changed. All other senders should not be affected.

The fix is dependent on the mail server software. I’ll show how to do this with SmarterMail since that’s what I use. We’ll set up a Content Filter to look for high priority messages from a certain sender, and add an action to reset the message’s priority.

1) Click the Settings button, expand My Settings, expand Filtering, then click Content Filtering. Your list may be blank. Mine already has three set up. Just click New to get started.

2) Turn on ‘From specific address’ and ‘Flagged as high priority’ and then click Next.

3) Make sure ‘AND’ is selected. Enter email addresses for the target senders.
Click Next.

4) Now finally the magic. Give this filter a Name. Turn on ‘Add Header’ and enter in whichever header name/value your email program listens to. For priority, Apple Mail uses the mail header “X-Priority”.  That is what I set to 0 (zero). Other mail clients use “Importance” and “X-MSMail-Priority”. Either of those you set to “Medium” instead of 0.
I also prefix the subject with an asterisk. That way I still know the sender thought this message was important, without gumming up everything else.
Click Save.

5) Send yourself a high priority test message. When it comes in, you should see that the Flag column is blank and there is now an asterisk in front of the Subject. When you see the asterisk, feel free to giggle like a school girl, ‘tee hee!’

Also take a look at the raw source. You’ll see that the the original X-Priority of 1 was overwritten with a zero.

Hooray, it works! =)

Want to read more?

Email, Mac OS X, Web Coding apple, Email, filters, importance, mail.app, priority, smartermail

WordPress – 301 location to sub page

August 10th, 2010

WordPress is great for blogging but still has a way to go to be a CMS. One thing I find odd is that you can create Categories for Posts but not for Pages. Usually a client will want pages categorized for navigation. So this becomes a problem. Sure you can nest Pages (parents and children) but that means you must have content in every menu item.

After a quick google search I came across some code that allows WP’s Pages to have empty menu items for categorization. Or at least that’s the visual effect. The fix is to create a Template in your theme with some PHP code. It redirects the browser to the first Child Page:

<?php
/*
Template Name: Redirect To First Child
*/
if (have_posts()) {
  while (have_posts()) {
  the_post();
  $pagekids = get_pages("child_of=".$post->ID."&sort_column=menu_order");
  $firstchild = $pagekids[0];
  wp_redirect(get_permalink($firstchild->ID));
 }
}
?>

This works but I’m not too fond of it. It uses a refresh. I tweaked it a bit. Changed the wp_redirect to a Location header and added a 301 status code:

<?php
/*
Template Name: 301 Redirect To First Child
*/
if (have_posts()) {
 while (have_posts()) {
  the_post();
  $pagekids = get_pages("child_of=".$post->ID."&sort_column=menu_order");
  $firstchild = $pagekids[0];
  header("HTTP/1.1 301 Moved Permanently");
  header("Location: ".get_permalink($firstchild->ID));
  exit();
 }
}
?>

This is much faster on the front end. It also tells search engines not to index those blank categorization pages.

<?php/*Template Name: 301 Redirect To First Child*/if (have_posts()) {  while (have_posts()) {    the_post();    $pagekids = get_pages(“child_of=”.$post->ID.”&sort_column=menu_order”);    $firstchild = $pagekids[0];   header(“HTTP/1.1 301 Moved Permanently”);   header(“Location: “.get_permalink($firstchild->ID));   exit();  }}?>

PHP 301, header, location, template, theme, WordPress

Updated compressed scripty 1.8.3 for LightView, PHP

April 8th, 2010

I ran across a problem with LightView which is stated as requiring Prototype 1.6.1 and Scriptaculous 1.8.2. Yet it was failing even when I had scriptaculous 1.8.3 loaded.

Apparently LightView looks for the loader scriptaculous.js rather than the actual components (effect, builder, etc).

My previous compressed Prototype 1.6.1 and Scriptaculous 1.8.3 did not have the loader/stub scriptaculous.js file. Ideally, that’s never needed as long as you load the other scriptaculous js files.

So here is an updated package. Also in this archive is the PHP version of the ColdFusion file to server the jgz.

The combined file is now 273KB. The load order is as follows:

prototype scriptaculous builder effects dragdrop controls slider sound

It includes all comments and credits. I gzipped it down to 62KB.

You’d load it like so:

<script type="text/javascript" charset="ISO-8859-1" src="/includes/js/scriptaculous/scriptaculous.cfm"></script>

Download it: wv-scripty-183.zip

ColdFusion, PHP, Scriptaculous

Custom scrollbars in Adium – ‘Elegant Simple’ Message Style

March 11th, 2010

Visually based on the “Pretty Simple” Message Style by Piotrek Marciniak, I’ve created a new breed of Adium Message Style – which boasts a completely custom scrollbar.

This message style is a working proof of concept. It is a prototype for the talented folks that create  wonderful message styles. I’m a developer, not an artist. I hope that others will use it as a spring board for rapid development of a whole new breed of message styles with custom scrollbars.

Since Adium Message Styles are really web pages, it only seemed right to mash up Prototype JS, LivePipe UI and Scriptaculous!

Features

Fade-in of messages Auto smooth scrolling when new message is received Custom styled scrollbar Dynamic height scrollbar handle Header and Footer objects of scrollbar handle Auto-hiding and fading scrollbar (mouse in/out of window) Mouse wheel support
Get the Flash Player to see the wordTube Media Player.

( View full size 800×600 MP4 3.7MB )

Go and get it!

Adium Xtras Github Repo (with source + media)

Adium, JavaScript, Mac OS X, Scriptaculous livepipe ui, prototype js, scrollbar, scroller

Visual Code Editor 1.2.5

March 4th, 2010

I’ve updated Visual Code Editor. Not so much an upgrade, but tested it out with SyntaxHighlighter Evolved 2.3.8 and WordPress 2.9.2.

SyntaxHighlighter Evolved fixes a lot of the problems that VCE also fixed (for SyntaxHighlighter Plus 1.x). But VCE still comes into play when you want to use tinyMCE (the post editor) in WordPress.

Adds `<pre>` & `<code>` to block format menu Allows extra attributes for compatibility in some syntax highlighters (ie, `<pre lang=”php” line=’5′>`) Unescape WP’s double escaping of & (not needed with SHE) Allows iFrames in the post Support for syntax highlighting in comments Removes extra `<pre>` tags around SyntaxHighllighter Plus’s sourcecode blocks

I tested it out with SHE and they both play very well together. Although the fixes in VCE are no longer needed, it still adds some functionality to the Visual Editor. Since nothing broke, I’m not going to fix it (remove the fixes). This allows its continued use in other client side syntax highlighters.

Go get it –> http://wordpress.org/extend/plugins/visual-code-editor/

Also, I highly recommend SyntaxHighlighter Evolved.

Visual Code Editor sourcecode, SyntaxHighlighter Evolved, SyntaxHighlighter Plus, TinyMCE, WordPress

Compressed Prototype 1.6.1 and Scriptaculous 1.8.3

February 3rd, 2010

I created a new compressed file for Prototype 1.6.1 and Scriptaculous 1.8.3. Included is my modified sound.js.

The combined file is 268KB. The load order is as follows:

prototype builder effects dragdrop controls slider sound

It includes all comments and credits. I gzipped it down to 60KB.

For your convenience in the attached zip contains both versions and a ColdFusion file to serve the correct one. You’d load it like so:

<script type="text/javascript" charset="ISO-8859-1" src="/includes/js/scriptaculous/scriptaculous.cfm"></script>

Well, what are you waiting for? :)wv-scripty-183.zip

JavaScript, Scriptaculous


You are viewing a mobilized version of this site...
View original page here

Mobilized by Mowser Mowser