<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>g-Off.net &#124; Geoffrey Foster</title>
	<atom:link href="http://g-Off.net/feed" rel="self" type="application/rss+xml" />
	<link>http://g-Off.net</link>
	<description></description>
	<lastBuildDate>Fri, 30 Oct 2009 00:12:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Announcing PyPush v0.1</title>
		<link>http://g-Off.net/software/announcing-pypush</link>
		<comments>http://g-Off.net/software/announcing-pypush#comments</comments>
		<pubDate>Wed, 14 Oct 2009 06:21:48 +0000</pubDate>
		<dc:creator>gfoster</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://g-Off.net/?p=134</guid>
		<description><![CDATA[Version 0.1 of PyPush is now available. PyPush is a rewrite/fork of apns-python-wrapper, that is, PyPush is a python module for interacting with Apples Push Notification Server.
Code is available from here where bugs can also be reported.
Visit the project page
Licensed under the Apache 2.0 license.
]]></description>
			<content:encoded><![CDATA[<p><img src="http://g-Off.net/wp-content/uploads/2009/10/sdk_icon3.png" alt="iPhone push notification" title="apns" width="66" height="79" class="alignleft size-full wp-image-117" />Version 0.1 of PyPush is now available. PyPush is a rewrite/fork of <a href="http://code.google.com/p/apns-python-wrapper/">apns-python-wrapper</a>, that is, PyPush is a python module for interacting with Apples Push Notification Server.</p>
<p>Code is available from <a href="http://bitbucket.org/g_Off/utilities/src/tip/python/pypush.py">here</a> where bugs can also be reported.</p>
<p><a href="http://g-Off.net/projects/pypush">Visit the project page</a></p>
<p>Licensed under the Apache 2.0 license.</p>
]]></content:encoded>
			<wfw:commentRss>http://g-Off.net/software/announcing-pypush/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MiraPay merchant support for WP e-Commerce</title>
		<link>http://g-Off.net/software/mirapay-wp-ecommerce</link>
		<comments>http://g-Off.net/software/mirapay-wp-ecommerce#comments</comments>
		<pubDate>Tue, 15 Sep 2009 18:14:09 +0000</pubDate>
		<dc:creator>gfoster</dc:creator>
				<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://g-Off.net/?p=135</guid>
		<description><![CDATA[WP e-Commerce is a WordPress plugin for adding shopping cart functionality to your WordPress powered website. I wanted to use it for a contract I did but it did not support the payment gateway that I had to use. So, I wrote one. It works and was used in a production website. It may need [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://g-Off.net/wp-content/uploads/2009/09/grey-m.png" alt="Wordpress logo" title="wordpress" width="100" height="100" class="alignright size-full wp-image-140" /><a href="http://www.instinct.co.nz/e-commerce/">WP e-Commerce</a> is a <a href="http://www.wordpress.org">WordPress</a> plugin for adding shopping cart functionality to your WordPress powered website. I wanted to use it for a contract I did but it did not support the payment gateway that I had to use. So, I wrote one. It works and was used in a production website. It may need some work to clean it up or whatnot but I have no plans to continue working on it. Feel free to use it if you need it, the code is released under the MIT license.</p>
<p><span id="more-135"></span></p>
<p>To use the code you will of course need a WordPress blog with the WP e-Commerce plugin installed. Download and save this file as mirapay.php and put it in the merchants directory within the wp-content/plugins/wp-e-commerce directory.</p>
<pre class="brush: php;">
&lt;?php
$nzshpcrt_gateways[$num]['name'] = 'Mirapay Payment';
$nzshpcrt_gateways[$num]['admin_name'] = 'Mirapay';
$nzshpcrt_gateways[$num]['internalname'] = 'mirapay';
$nzshpcrt_gateways[$num]['function'] = 'gateway_mirapay';
$nzshpcrt_gateways[$num]['form'] = &quot;form_mirapay&quot;;
$nzshpcrt_gateways[$num]['submit_function'] = &quot;submit_mirapay&quot;;

function gateway_mirapay($seperator, $sessionid) {
    global $wpdb;

    $_SESSION['mirapaysessionid'] = $sessionid;

    $purchase_log_sql = &quot;SELECT * FROM `&quot;.$wpdb-&gt;prefix.&quot;purchase_logs` WHERE `sessionid`= &quot;.$sessionid.&quot; LIMIT 1&quot;;
	$purchase_log = $wpdb-&gt;get_results($purchase_log_sql,ARRAY_A);

    $cart_sql = &quot;SELECT * FROM `&quot;.$wpdb-&gt;prefix.&quot;cart_contents` WHERE `purchaseid`='&quot;.$purchase_log[0]['id'].&quot;'&quot;;
	$cart = $wpdb-&gt;get_results($cart_sql,ARRAY_A);

    $transact_url = get_option('transact_url');
    $mirapay_url = get_option('mirapay_url');

	$total_price = 0;
	foreach($cart as $item) {
		$product_data = $wpdb-&gt;get_results(&quot;SELECT * FROM `&quot;.$wpdb-&gt;prefix.&quot;product_list` WHERE `id`='&quot;.$item['prodid'].&quot;' LIMIT 1&quot;,ARRAY_A);
		$product_data = $product_data[0];

		$total_price = $total_price + ($item['price'] * $item['quantity']);
	}

 	$data['MTID'] = $sessionid;
 	$data['Merchant_ID'] = get_option('mirapay_merchant_id');
 	$data['Amount1'] = number_format($total_price, 2);

	if(get_option('mirapay_debug') == 1) {
        $output = &quot;&lt;form id=\&quot;mirapay_form\&quot; name=\&quot;mirapay_form\&quot; method=\&quot;get\&quot; action=\&quot;&quot;.$transact_url.$seperator.&quot;sessionid=&quot;.$sessionid.&quot;&amp;gateway=mirapay&quot;.&quot;\&quot;&gt;\n&quot;;
        $output .= &quot;&lt;input type=\&quot;hidden\&quot; name=\&quot;debug\&quot; value=\&quot;true\&quot; /&gt;&quot;;
	    $output .= &quot;&lt;select name=\&quot;Response\&quot;&gt;&quot;;
        $output .= &quot;&lt;option value=\&quot;APPROVED\&quot;&gt;Accepted&lt;/option&gt;&quot;;
        $output .= &quot;&lt;option value=\&quot;DECLINED\&quot;&gt;Declined&lt;/option&gt;&quot;;
        $output .= &quot;&lt;option value=\&quot;CANCELED\&quot;&gt;Cancelled&lt;/option&gt;&quot;;
        $output .= &quot;&lt;/select&gt;&quot;;
        $data['MiraID'] = &quot;DEBUG&quot;;
        $data['gateway'] = &quot;mirapay&quot;;
    } else {
        if($_POST['collected_data'][get_option('mirapay_form_email')] != '') {
        	$data['EMail'] = $_POST['collected_data'][get_option('mirapay_form_email')];
        }
        $data['SuccessURL'] = $transact_url.$seperator.&quot;sessionid=&quot;.$sessionid.&quot;&amp;gateway=mirapay&quot;;
        $data['FailURL'] = $transact_url.$seperator.&quot;&amp;gateway=mirapay&quot;;
        $data['MKEY'] = md5($sessionid.number_format($total_price, 2).get_option('mirapay_salt'));

        $output = &quot;&lt;form id=\&quot;mirapay_form\&quot; name=\&quot;mirapay_form\&quot; method=\&quot;post\&quot; action=\&quot;$mirapay_url\&quot;&gt;\n&quot;;
    }
	foreach($data as $n=&gt;$v) {
			$output .= &quot;&lt;input type=\&quot;hidden\&quot; name=\&quot;$n\&quot; value=\&quot;$v\&quot; /&gt;\n&quot;;
	}
	$output .= &quot;You are being automatically re-directed to MiraPay. If this does not occur please click here: &lt;input type=\&quot;submit\&quot; value=\&quot;Continue to MiraPay\&quot; /&gt;
		&lt;/form&gt;
	&quot;;

	if(get_option('mirapay_debug') == 1) {
		echo (&quot;DEBUG MODE ON!!&lt;br/&gt;&quot;);
		echo(&quot;The following form is created and would be posted to MiraPay for processing.  Press submit to continue:&lt;br/&gt;&quot;);
		echo(&quot;&lt;pre&gt;&quot;.htmlspecialchars($output).&quot;&lt;/pre&gt;&quot;);
	}

	echo($output);

	if(get_option('mirapay_debug') == 0) {
		echo &quot;&lt;script language=\&quot;javascript\&quot; type=\&quot;text/javascript\&quot;&gt;document.getElementById('mirapay_form').submit();&lt;/script&gt;&quot;;
	}

    exit();
}

function g_off_mirapay_callback()
{
    global $wpdb;

    if($_GET['gateway'] == 'mirapay') {
        $mtid = trim(stripslashes($_GET['MTID']));
        $response = trim(stripslashes($_GET['Response']));
        $miraid = trim(stripslashes($_GET['MiraID']));
        $mkey = trim(stripslashes($_GET['MKEY']));
        $amount = trim(stripslashes($_GET['Amount1']));
        $sessionid = $mtid; //_SESSION['mirasessionid'];

        if($_GET['debug'] == 'true' &amp;&amp; get_option('mirapay_debug') == 1) {
            $mkey = md5($mtid.number_format($amount,2).$miraid.$response.get_option('mirapay_salt'));
            // print_r($_GET);
            // reset($_GET);
        }

        $transation_id = $mkey;
        $genhash = md5($mtid.number_format($amount,2).$miraid.$response.get_option('mirapay_salt'));

        if($genhash == $mkey) {
            $_GET['sessionid'] = $sessionid;
            switch($response) {
                case 'APPROVED':
                    // echo &quot;purchase succeeded\n&quot;;
                    // echo &quot;UPDATE `&quot;.$wpdb-&gt;prefix.&quot;purchase_logs` SET
                    //                      `processed` = '2',
                    //                      `transactid` = '&quot;.$transaction_id.&quot;',
                    //                      `date` = '&quot;.time().&quot;' WHERE `sessionid` = &quot;.$sessionid.&quot; LIMIT 1&quot;;
                    $wpdb-&gt;query(&quot;UPDATE `&quot;.$wpdb-&gt;prefix.&quot;purchase_logs` SET
                                         `processed` = '2',
                                         `transactid` = '&quot;.$transaction_id.&quot;',
                                         `date` = '&quot;.time().&quot;' WHERE `sessionid` = &quot;.$sessionid.&quot; LIMIT 1&quot;);

                     transaction_results($sessionid, false, $transaction_id);
                     // $transact_url = get_option('transact_url');
                     // unset($_SESSION['WpscGatewayErrorMessage']);
                     // header(&quot;Location: &quot;.$transact_url.$seperator.&quot;sessionid=&quot;.$sessionid);
                    break;
                case 'DECLINED':
                    $log_id = $wpdb-&gt;get_var(&quot;SELECT `id` FROM `&quot;.$wpdb-&gt;prefix.&quot;purchase_logs` WHERE `sessionid`='$sessionid' LIMIT 1&quot;);
                    $delete_log_form_sql = &quot;SELECT * FROM `&quot;.$wpdb-&gt;prefix.&quot;cart_contents` WHERE `purchaseid`='$log_id'&quot;;
                    $cart_content = $wpdb-&gt;get_results($delete_log_form_sql,ARRAY_A);
                    foreach((array)$cart_content as $cart_item) {
                        $cart_item_variations = $wpdb-&gt;query(&quot;DELETE FROM `&quot;.$wpdb-&gt;prefix.&quot;cart_item_variations` WHERE `cart_id` = '&quot;.$cart_item['id'].&quot;'&quot;, ARRAY_A);
                    }
                    $wpdb-&gt;query(&quot;DELETE FROM `&quot;.$wpdb-&gt;prefix.&quot;cart_contents` WHERE `purchaseid`='$log_id'&quot;);
                    $wpdb-&gt;query(&quot;DELETE FROM `&quot;.$wpdb-&gt;prefix.&quot;submited_form_data` WHERE `log_id` IN ('$log_id')&quot;);
                    $wpdb-&gt;query(&quot;DELETE FROM `&quot;.$wpdb-&gt;prefix.&quot;purchase_logs` WHERE `id`='$log_id' LIMIT 1&quot;);

                    break;
                case 'CANCELED':
                    $log_id = $wpdb-&gt;get_var(&quot;SELECT `id` FROM `&quot;.$wpdb-&gt;prefix.&quot;purchase_logs` WHERE `sessionid`='$sessionid' LIMIT 1&quot;);
                    $delete_log_form_sql = &quot;SELECT * FROM `&quot;.$wpdb-&gt;prefix.&quot;cart_contents` WHERE `purchaseid`='$log_id'&quot;;
                    $cart_content = $wpdb-&gt;get_results($delete_log_form_sql,ARRAY_A);
                    foreach((array)$cart_content as $cart_item) {
                        $cart_item_variations = $wpdb-&gt;query(&quot;DELETE FROM `&quot;.$wpdb-&gt;prefix.&quot;cart_item_variations` WHERE `cart_id` = '&quot;.$cart_item['id'].&quot;'&quot;, ARRAY_A);
                    }
                    $wpdb-&gt;query(&quot;DELETE FROM `&quot;.$wpdb-&gt;prefix.&quot;cart_contents` WHERE `purchaseid`='$log_id'&quot;);
                    $wpdb-&gt;query(&quot;DELETE FROM `&quot;.$wpdb-&gt;prefix.&quot;submited_form_data` WHERE `log_id` IN ('$log_id')&quot;);
                    $wpdb-&gt;query(&quot;DELETE FROM `&quot;.$wpdb-&gt;prefix.&quot;purchase_logs` WHERE `id`='$log_id' LIMIT 1&quot;);

                    header(&quot;Location: &quot;.get_option('shopping_cart_url'));
                    exit;

                    break;
                default:
                    break;
            }
        } else {
            //      $message = &quot;This message has been sent because a call to your ChronoPay function was made by a server that did not have the correct security key.  This could mean someone is trying to hack your payment site.  The details of the call are below.\n\r\n\r&quot;;
            //      $message .= &quot;OUR_POST:\n\r&quot;.print_r($header . $req,true).&quot;\n\r\n\r&quot;;
            //      $message .= &quot;THEIR_POST:\n\r&quot;.print_r($_POST,true).&quot;\n\r\n\r&quot;;
            //      $message .= &quot;GET:\n\r&quot;.print_r($_GET,true).&quot;\n\r\n\r&quot;;
            //      $message .= &quot;SERVER:\n\r&quot;.print_r($_SERVER,true).&quot;\n\r\n\r&quot;;
            //      mail(get_option('purch_log_email'), &quot;ChronoPay Security Key Failed!&quot;, $message);
        }
    }
}

function submit_mirapay() {
	if($_POST['mirapay_merchant_id'] != null)
    {
    	update_option('mirapay_merchant_id', $_POST['mirapay_merchant_id']);
    }

  	if($_POST['mirapay_url'] != null)
    {
    	update_option('mirapay_url', $_POST['mirapay_url']);
    }

  	if($_POST['mirapay_salt'] != null)
    {
    	update_option('mirapay_salt', $_POST['mirapay_salt']);
    }

  	if($_POST['mirapay_curcode'] != null)
    {
    	update_option('mirapay_curcode', $_POST['mirapay_curcode']);
    }

 	if($_POST['mirapay_language'] != null)
    {
    	update_option('mirapay_language', $_POST['mirapay_language']);
    }

  	if($_POST['mirapay_debug'] != null)
    {
    	update_option('mirapay_debug', $_POST['mirapay_debug']);
    }

	foreach((array)$_POST['mirapay_form'] as $form =&gt; $value)
    {
    	update_option(('mirapay_form_'.$form), $value);
    }
	return true;
}

function form_mirapay() {
	$mirapay_url = ( get_option('mirapay_url')=='' ? 'https://www3.eigendev.com/mirapay/secure_credit.php' : get_option('mirapay_url') );
	$mirapay_salt = ( get_option('mirapay_salt')=='' ? 'changeme' : get_option('mirapay_salt') );

	$mirapay_debug = get_option('mirapay_debug');
	$mirapay_debug1 = &quot;&quot;;
	$mirapay_debug2 = &quot;&quot;;
	switch($mirapay_debug)
	{
		case 0:
			$mirapay_debug2 = &quot;checked ='true'&quot;;
			break;
		case 1:
			$mirapay_debug1 = &quot;checked ='true'&quot;;
			break;
	}

	$output = &quot;
		&lt;tr&gt;
			&lt;td&gt;MiraPay Merchant ID&lt;/td&gt;
			&lt;td&gt;&lt;input type='text' size='40' value='&quot;.get_option('mirapay_merchant_id').&quot;' name='mirapay_merchant_id' /&gt;&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&amp;nbsp;&lt;/td&gt;
			&lt;td&gt;&lt;small&gt;This should be set to your MiraPay Merchant ID.
			This is the MiraPay Merchant ID that all purchases will be processed against.&lt;/small&gt;&lt;/td&gt;
		&lt;/tr&gt;

		&lt;tr&gt;
			&lt;td&gt;MiraPay processing URL&lt;/td&gt;
			&lt;td&gt;&lt;input type='text' size='40' value='&quot;.$mirapay_url.&quot;' name='mirapay_url' /&gt;&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&amp;nbsp;&lt;/td&gt;
			&lt;td&gt;&lt;small&gt;URL of the secure payment page customers are sent to for payment processing. If unsure leave at default setting.&lt;/small&gt;&lt;/td&gt;
		&lt;/tr&gt;

		&lt;tr&gt;
			&lt;td&gt;MiraPay Security Key&lt;/td&gt;
			&lt;td&gt;&lt;input type='text' size='40' value='&quot;.$mirapay_salt.&quot;' name='mirapay_salt' /&gt;&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&amp;nbsp;&lt;/td&gt;
			&lt;td&gt;&lt;small&gt;A bit of security... This is a keyword that is used to ensure transaction approval calls from MiraPay to this application are real and were instigated from this server.  Enter a unique word into this field.&lt;/small&gt;&lt;/td&gt;
		&lt;/tr&gt;

		&lt;tr&gt;
			&lt;td&gt;MiraPay Accepted Currency (CAD)&lt;/td&gt;
			&lt;td&gt;&lt;select name='mirapay_curcode'&gt;
					&lt;option &quot;.$select_currency['CAD'].&quot; value='CAD'&gt;CAD - Canadian Dollar&lt;/option&gt;
				&lt;/select&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&amp;nbsp;&lt;/td&gt;
			&lt;td&gt;&lt;small&gt;The currency code that MiraPay will process the payment in. All products must be set up in this currency.&lt;/small&gt;&lt;/td&gt;
		&lt;/tr&gt;

		&lt;tr&gt;
			&lt;td&gt;MiraPay Language&lt;/td&gt;
			&lt;td&gt;&lt;select name='mirapay_language'&gt;
					&lt;option &quot;.$select_language['EN'].&quot; value='EN'&gt;Engish&lt;/option&gt;
					&lt;option &quot;.$select_language['ES'].&quot; value='FR'&gt;French&lt;/option&gt;
				&lt;/select&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&amp;nbsp;&lt;/td&gt;
			&lt;td&gt;&lt;small&gt;The language that the MiraPay secure processing page will be displayed in.&lt;/small&gt;&lt;/td&gt;
		&lt;/tr&gt;

		&lt;tr&gt;
			&lt;td&gt;MiraPay Debug Mode&lt;/td&gt;
			&lt;td&gt;
				&lt;input type='radio' value='1' name='mirapay_debug' id='mirapay_debug1' &quot;.$mirapay_debug1.&quot; /&gt; &lt;label for='mirapay_debug1'&gt;&quot;.TXT_WPSC_YES.&quot;&lt;/label&gt; &amp;nbsp;
				&lt;input type='radio' value='0' name='mirapay_debug' id='mirapay_debug2' &quot;.$mirapay_debug2.&quot; /&gt; &lt;label for='mirapay_debug2'&gt;&quot;.TXT_WPSC_NO.&quot;&lt;/label&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;&amp;nbsp;&lt;/td&gt;
			&lt;td&gt;&lt;small&gt;Debug mode is used to write HTTP communications between the MiraPay server and your host to a log file.  This should only be activated for testing!&lt;/small&gt;&lt;/td&gt;
		&lt;/tr&gt;

	&lt;tr class='update_gateway' &gt;
		&lt;td colspan='2'&gt;
			&lt;div class='submit'&gt;
			&lt;input type='submit' value='Update &amp;raquo;' name='updateoption'/&gt;
		&lt;/div&gt;
		&lt;/td&gt;
	&lt;/tr&gt;

	&lt;tr class='firstrowth'&gt;
		&lt;td style='border-bottom: medium none;' colspan='2'&gt;
			&lt;strong class='form_group'&gt;Forms Sent to Gateway&lt;/strong&gt;
		&lt;/td&gt;
	&lt;/tr&gt;

		&lt;tr&gt;
			&lt;td&gt;First Name Field&lt;/td&gt;
			&lt;td&gt;&lt;select name='mirapay_form[first_name]'&gt;
				&quot;.nzshpcrt_form_field_list(get_option('mirapay_form_first_name')).&quot;
				&lt;/select&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Last Name Field&lt;/td&gt;
			&lt;td&gt;&lt;select name='mirapay_form[last_name]'&gt;
				&quot;.nzshpcrt_form_field_list(get_option('mirapay_form_last_name')).&quot;
				&lt;/select&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Address Field&lt;/td&gt;
			&lt;td&gt;&lt;select name='mirapay_form[address]'&gt;
				&quot;.nzshpcrt_form_field_list(get_option('mirapay_form_address')).&quot;
				&lt;/select&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;City Field&lt;/td&gt;
			&lt;td&gt;&lt;select name='mirapay_form[city]'&gt;
				&quot;.nzshpcrt_form_field_list(get_option('mirapay_form_city')).&quot;
				&lt;/select&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;State Field&lt;/td&gt;
			&lt;td&gt;&lt;select name='mirapay_form[state]'&gt;
				&quot;.nzshpcrt_form_field_list(get_option('mirapay_form_state')).&quot;
				&lt;/select&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Postal code/Zip code Field&lt;/td&gt;
			&lt;td&gt;&lt;select name='mirapay_form[post_code]'&gt;
				&quot;.nzshpcrt_form_field_list(get_option('mirapay_form_post_code')).&quot;
				&lt;/select&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Country Field&lt;/td&gt;
			&lt;td&gt;&lt;select name='mirapay_form[country]'&gt;
				&quot;.nzshpcrt_form_field_list(get_option('mirapay_form_country')).&quot;
				&lt;/select&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;Email Field&lt;/td&gt;
			&lt;td&gt;&lt;select name='mirapay_form[email]'&gt;
				&quot;.nzshpcrt_form_field_list(get_option('mirapay_form_email')).&quot;
				&lt;/select&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
	&quot;;
	return $output;
}

add_action('init', 'g_off_mirapay_callback', 5);
</pre>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://g-Off.net/software/mirapay-wp-ecommerce/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CLLocation forward GeoLocation method</title>
		<link>http://g-Off.net/software/cllocation-forward-geolocation-method</link>
		<comments>http://g-Off.net/software/cllocation-forward-geolocation-method#comments</comments>
		<pubDate>Mon, 17 Aug 2009 03:54:42 +0000</pubDate>
		<dc:creator>gfoster</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[CoreLocation]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://g-Off.net/?p=93</guid>
		<description><![CDATA[The new MapKit framework for the iPhone OS 3.0 provides a very easy to use way of doing reverse geolocation (getting address information by providing latitude and longitude). But, it would seem that there is nothing built in for getting latitude and longitude values for a given address. Luckily, Google to the rescue! The following [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://g-Off.net/wp-content/uploads/2009/08/sdk_icon4.png" alt="iPhone Maps App icon" title="iPhone Maps App icon" width="66" height="79" class="alignleft size-full wp-image-117" />The new MapKit framework for the iPhone OS 3.0 provides a very easy to use way of doing reverse geolocation (getting address information by providing latitude and longitude). But, it would seem that there is nothing built in for getting latitude and longitude values for a given address. Luckily, Google to the rescue! <span id="more-93"></span>The following code-snippet is a category on CLLocation with the one method</p>

<div class="wp_codebox"><table><tr id="p933"><td class="code" id="p93code3"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span>CLLocation <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>locationUsingForwardGeoLocation<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/"><span style="color: #400080;">NSString</span></a> <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>address;</pre></td></tr></table></div>

<p> which takes an address string, and, using Google maps API, does a lookup and returns a CLLocation object for the given address. If no address could be found then nil is returned.</p>
<p>Usage is very simple:</p>

<div class="wp_codebox"><table><tr id="p934"><td class="code" id="p93code4"><pre class="objc" style="font-family:monospace;">CLLocation <span style="color: #002200;">*</span>ottawa <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>CLLocation locationUsingForwardGeoLocation<span style="color: #002200;">:</span><span style="color: #bf1d1a;">@</span><span style="color: #bf1d1a;">&quot;Ottawa, Ontario&quot;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #11740a; font-style: italic;">// Do whatever with the returned CLLocation object</span></pre></td></tr></table></div>

<p>CLLocation+ForwardGeoLocation.h <a href="http://bitbucket.org/g_Off/utilities/src/tip/cocoa/iphone/CLLocation+ForwardGeoLocation.h">View</a><br />
CLLocation+ForwardGeoLocation.m <a href="http://bitbucket.org/g_Off/utilities/src/tip/cocoa/iphone/CLLocation+ForwardGeoLocation.m">View</a></p>
<p><a href="http://bitbucket.org/g_Off/utilities/issues/new/">Report any bugs or issues here</a></p>
<p>Credit for some of the code and the original idea go to <a href="http://mithin.in/2009/06/22/using-iphone-sdk-mapkit-framework-a-tutorial/">http://mithin.in/2009/06/22/using-iphone-sdk-mapkit-framework-a-tutorial/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://g-Off.net/software/cllocation-forward-geolocation-method/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cappuccino/Objective-J and URLTextField</title>
		<link>http://g-Off.net/software/cappuccinoobjective-j-and-urltextfield</link>
		<comments>http://g-Off.net/software/cappuccinoobjective-j-and-urltextfield#comments</comments>
		<pubDate>Thu, 19 Mar 2009 01:32:25 +0000</pubDate>
		<dc:creator>gfoster</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[cappuccino]]></category>
		<category><![CDATA[objective-j]]></category>
		<category><![CDATA[objj]]></category>

		<guid isPermaLink="false">http://g-Off.net/?p=34</guid>
		<description><![CDATA[I wanted to display a link in a Cappuccino web application but there doesn't seem to be a very "nice" way of doing that so I wrote up the URLTextField class. It's basically a regular CPTextField but the CPTextFields DOMElement is wrapped in another DOMElement that provides the anchor tag. Use it like a normal [...]]]></description>
			<content:encoded><![CDATA[<p>I wanted to display a link in a <a href="http://www.cappuccino.org">Cappuccino</a> web application but there doesn't seem to be a very "nice" way of doing that so I wrote up the URLTextField class. It's basically a regular CPTextField but the CPTextFields DOMElement is wrapped in another DOMElement that provides the anchor tag. Use it like a normal CPTextField and call setStringValue: with the text you'd like displayed for the link, and use setLink: with a valid URL to set the link. A convenience initWithFrame:link:title: is also available that sets it all up from the get-go.<span id="more-34"></span></p>

<div class="wp_codebox"><table><tr id="p346"><td class="code" id="p34code6"><pre class="objj" style="font-family:monospace;">// Copyright (c) 2009 Geoffrey Foster
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the &quot;Software&quot;), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
&nbsp;
@import &lt;AppKit/CPTextField.j&gt;
&nbsp;
@implementation URLTextField : CPTextField
{
    CPString _link;
    DOMElement _DOMAnchorElement;
}
&nbsp;
- (id)initWithFrame:(CGRect)aFrame
{
    return [self initWithFrame:aFrame link:@&quot;&quot; title:@&quot;&quot;];
}
&nbsp;
- (id)initWithFrame:(CGRect)aFrame link:(CPString)link title:(CPString)title
{
    if(self = [super initWithFrame:aFrame])
    {
		_link = link;
		[super setStringValue:title];
&nbsp;
        _DOMAnchorElement = document.createElement(&quot;a&quot;);
        _DOMAnchorElement.href = link;
        _DOMAnchorElement.title = title;
&nbsp;
        var element = _DOMElement.removeChild(_DOMTextElement);
        element.style.cursor = &quot;pointer&quot;;
        _DOMAnchorElement.appendChild(element);
        _DOMElement.appendChild(_DOMAnchorElement);
	}
	return self;
}
&nbsp;
- (void)setLink:(CPString)link
{
    _link = link;
    _DOMAnchorElement.href = _link;
}
- (CPString)getLink
{
    return _link;
}
&nbsp;
- (void)setStringValue:(CPString)anObject
{
    [super setStringValue:anObject];
    _DOMAnchorElement.title = anObject;
    [super sizeToFit];
}
&nbsp;
@end</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://g-Off.net/software/cappuccinoobjective-j-and-urltextfield/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Python repeatable threading.Timer class</title>
		<link>http://g-Off.net/software/a-python-repeatable-threadingtimer-class</link>
		<comments>http://g-Off.net/software/a-python-repeatable-threadingtimer-class#comments</comments>
		<pubDate>Wed, 18 Mar 2009 19:20:00 +0000</pubDate>
		<dc:creator>gfoster</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[threading]]></category>

		<guid isPermaLink="false">http://g-Off.net/?p=11</guid>
		<description><![CDATA[I had a function that I wanted to be called repeatedly every x seconds but couldn't find a nice way of doing this. The python threading module has a Timer class which will wait for the given number of seconds and then execute the passed in callable object. Unfortunately, once it has executed that code [...]]]></description>
			<content:encoded><![CDATA[<p>I had a function that I wanted to be called repeatedly every x seconds but couldn't find a nice way of doing this. The python threading module has a Timer class which will wait for the given number of seconds and then execute the passed in callable object. Unfortunately, once it has executed that code it is no longer useable. So based upon that class I whipped up the following RepeatableTimer. It's not "hard real-time" or anything since it doesn't account for the time taken to execute the given function, but it's good enough for what I needed.<span id="more-11"></span> Feel free to use it however you see fit as I'm distributing it under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT</a> license.</p>
<h3>Usage:</h3>
<p> Create a new RepeatTimer object passing it required arguments and any optional ones.</p>
<h4>Required Arguments:</h4>
<ul title="required arguments">
<li>interval -- floating point number specifying the number of seconds to wait before executing function</li>
<li>function -- the function (or callable object) to be executed</li>
</ul>
<h4>Optional Arguments:</h4>
<ul title="optional arguments">
<li>iterations -- integer specifying the number of iterations to perform</li>
<li>args -- list of positional arguments passed to function</li>
<li>kwargs -- dictionary of keyword arguments passed to function</li>
</ul>
<h3>Examples:</h3>
<p>Execute the hello function every 5 seconds:</p>

<div class="wp_codebox"><table><tr id="p1110"><td class="code" id="p11code10"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> hello<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Hello World!&quot;</span>
&nbsp;
r = RepeatTimer<span style="color: black;">&#40;</span><span style="color: #ff4500;">5.0</span>, hello<span style="color: black;">&#41;</span>
r.<span style="color: black;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>Execute the hello function every 5 seconds but terminate when it has executed 10 times:</p>

<div class="wp_codebox"><table><tr id="p1111"><td class="code" id="p11code11"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> hello<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Hello World!&quot;</span>
&nbsp;
r = RepeatTimer<span style="color: black;">&#40;</span><span style="color: #ff4500;">5.0</span>, hello, <span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span>
r.<span style="color: black;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>


<div class="wp_codebox"><table><tr id="p1112"><td class="code" id="p11code12"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;"># Copyright (c) 2009 Geoffrey Foster</span>
<span style="color: #808080; font-style: italic;"># </span>
<span style="color: #808080; font-style: italic;"># Permission is hereby granted, free of charge, to any person</span>
<span style="color: #808080; font-style: italic;"># obtaining a copy of this software and associated documentation</span>
<span style="color: #808080; font-style: italic;"># files (the &quot;Software&quot;), to deal in the Software without</span>
<span style="color: #808080; font-style: italic;"># restriction, including without limitation the rights to use,</span>
<span style="color: #808080; font-style: italic;"># copy, modify, merge, publish, distribute, sublicense, and/or sell</span>
<span style="color: #808080; font-style: italic;"># copies of the Software, and to permit persons to whom the</span>
<span style="color: #808080; font-style: italic;"># Software is furnished to do so, subject to the following</span>
<span style="color: #808080; font-style: italic;"># conditions:</span>
<span style="color: #808080; font-style: italic;"># </span>
<span style="color: #808080; font-style: italic;"># The above copyright notice and this permission notice shall be</span>
<span style="color: #808080; font-style: italic;"># included in all copies or substantial portions of the Software.</span>
<span style="color: #808080; font-style: italic;"># </span>
<span style="color: #808080; font-style: italic;"># THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND,</span>
<span style="color: #808080; font-style: italic;"># EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES</span>
<span style="color: #808080; font-style: italic;"># OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND</span>
<span style="color: #808080; font-style: italic;"># NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT</span>
<span style="color: #808080; font-style: italic;"># HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,</span>
<span style="color: #808080; font-style: italic;"># WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING</span>
<span style="color: #808080; font-style: italic;"># FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR</span>
<span style="color: #808080; font-style: italic;"># OTHER DEALINGS IN THE SOFTWARE.</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">threading</span> <span style="color: #ff7700;font-weight:bold;">import</span> Event, Thread
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> RepeatTimer<span style="color: black;">&#40;</span>Thread<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, interval, function, iterations=<span style="color: #ff4500;">0</span>, args=<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>, kwargs=<span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>:
        Thread.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">interval</span> = interval
        <span style="color: #008000;">self</span>.<span style="color: black;">function</span> = function
        <span style="color: #008000;">self</span>.<span style="color: black;">iterations</span> = iterations
        <span style="color: #008000;">self</span>.<span style="color: black;">args</span> = args
        <span style="color: #008000;">self</span>.<span style="color: black;">kwargs</span> = kwargs
        <span style="color: #008000;">self</span>.<span style="color: black;">finished</span> = Event<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> run<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        count = <span style="color: #ff4500;">0</span>
        <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">finished</span>.<span style="color: black;">is_set</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">iterations</span> <span style="color: #66cc66;">&lt;</span>= <span style="color: #ff4500;">0</span> <span style="color: #ff7700;font-weight:bold;">or</span> count <span style="color: #66cc66;">&lt;</span> <span style="color: #008000;">self</span>.<span style="color: black;">iterations</span><span style="color: black;">&#41;</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">finished</span>.<span style="color: black;">wait</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">interval</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">self</span>.<span style="color: black;">finished</span>.<span style="color: black;">is_set</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">function</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: #008000;">self</span>.<span style="color: black;">args</span>, <span style="color: #66cc66;">**</span><span style="color: #008000;">self</span>.<span style="color: black;">kwargs</span><span style="color: black;">&#41;</span>
                count += <span style="color: #ff4500;">1</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> cancel<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #008000;">self</span>.<span style="color: black;">finished</span>.<span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p><strong>Updated</strong> <em>Oct 29, 2009</em>: Removed extra unneeded Event object.</p>
]]></content:encoded>
			<wfw:commentRss>http://g-Off.net/software/a-python-repeatable-threadingtimer-class/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>
