Programming

SQL Server Stem Words

Posted in Troubleshooting on February 28th, 2011 by Jamie – Be the first to comment

We needed to find related words using the SQL Server FORMSOF function. Although it is used mainly to find related words in bodies of text, we wanted to use it to find related words in a table of just words. Initial approaches focused on finding a SQL Function or table that contained the database of related words. This turned out to be a dead end.

We decided a clever approach would be to iterate through each row of the table, using it to query all the rows. This would create groupings of words that could be used to tie them together, via a common group ID.

Although a better solution may have been to use a indexing engine such as Lucene to generate the correspondences, we were already using SQL Server’s functions.

Regex Challenge

Posted in Troubleshooting on February 25th, 2011 by Jamie – Be the first to comment

A friend asked for a regex that matches a paragraph that contains only upper-case text inside a nested hierarchy of tags. Some examples:

Matches:


<p class="abcdefg"><a href="1.htm"><span>HELLO THERE</span></a></p>
<p class="c8"><span class="c7">BY ERIC D. JAMES, MD</span></p>
<p style="border:1px solid red">HELLO DARLING</p>

Fail:


<p class="c8"><span class="c7">BY Eric James, MD</span></p>
<p style="border:1px solid red">Hello Darling</p>
<p class="abcdefg"><a href="1.htm"><span>HELLO THeRE</span></a></p>

I came up with the following expression:

/<p[^>]*>(<[^>]*>)*[^a-z<]+(<\/[^p][^>]*>)*<\/p[^>]*>/

It doesn’t handle tags interspersed with text or nested paragraph tags.

Here’s a sample on Rubular.

Dominos-Style Game

Posted in Libraries on February 14th, 2011 by Jamie – Be the first to comment

My wife loves PopCap’s game Alchemy. It’s a dominoes-like game, where you match up alchemic symbols and various colors. The object of the game is to turn each board-square from lead to gold. I have been wanting to try out the limejs game library, which is based on Google’s Closure compiler, so I decided to write a quick implementation of the game. You can find the source on Github.

You can try out the game online. To play, place pieces adjacent to other pieces which match in symbol or color. A placed piece must match all the pieces adjacent to it. A wild card piece, denoted with the ‘*’ symbol, matches all pieces. Filling a row or column with pieces will mark the corresponding spaces as cleared. The object of the game is to get each space marked as cleared.

Edit (20100214 11:00 PM): Added win condition and box showing how many spaces cleared.
Edit (20100215 11:00 PM): Added leveling. The board starts small with few pieces and keeps getting bigger with each round.

Adding comments to spreadsheets with POI

Posted in Troubleshooting on February 7th, 2011 by Jamie – 1 Comment

I was just recently working on a project using NPOI, the .NET equivalent of POI, which is a great library for writing Microsoft Office documents. I was using HSSF, it’s spreadsheet library (Horrible Spreadsheet Format according to Google), and attempting to add Comments to cells.

At first I thought it wasn’t working at all. Then I noticed there was a single cell that had the little red marker that tells you there is a comment. After a little debugging, I realized that this was the last comment added, and guessed that I was doing something to clear the comments I created with each loop iteration.

The block of code that creates comments is something like:

HSSFCell cell //...
// ...
HSSFPatriarch patr = sheet.CreateDrawingPatriarch(); // should only be called once
HSSFComment hssfComment = (HSSFComment) patr.CreateCellComment(
    new HSSFClientAnchor(0, 0, 0, 0,
    cell.ColumnIndex, cell.RowIndex, // start cell index (for size)
    cell.ColumnIndex+4, cell.RowIndex+6) // end cell index (for size)
    );
hssfComment.String = new HSSFRichTextString("Comment text");
cell.CellComment = hssfComment;

Unfortunately I had been creating the drawing patriarch in each loop. I didn’t realize it should be a top-level container for the comments. So make sure to not re-create the drawing patriarch.

Weird Sammy + jQuery on IE error

Posted in Troubleshooting on January 28th, 2011 by Jamie – Be the first to comment

Here’s a post that might help problems with Sammy routes, callbacks, and event handlers using jQuery, especially the “live” function.

I have an input form with submit buttons like:

<form>
<input type="submit" name="what" value="SomeCommand" />
<input type="submit" name="what" value="DifferentCommand" />
</form>

This didn’t play well with Sammy, as it doesn’t load the value of what into it’s params hash. So, I did a work around like:

  // hack to allow sammy to access the 'what' param
  $('form input[type=submit]').live('click', function(){
    var submit = $(this),
      form = submit.parents('form');
    form.find('input[name=what][type=hidden]').val(submit.val());
  });

I’m not sure why I originally chose to use “live.” It could’ve been that I was building DOM dynamically using jquery-tmpl. In Firefox and Chrome, this worked as expected. In IE, the Sammy route handler would fire before the click handler above! So, I changed the code to use the non-live version.

  $('form input[type=submit]').click(function(){ // changed
    ...
  });

Innovation Tournament

Posted in Software on January 13th, 2011 by Jamie – Be the first to comment

This week I was in San Francisco participating in a Wharton class about innovation. We had a week to sort through various ideas for web products and create a prototype. I worked on two projects. One is a lottery site, with a simple demo available. I got to use the Youtube API for playing a video and then performing some action upon completion. It was  a little clunky to get setup, but afterwards worked flawlessly.

The other was an idea for a social dashboard for restaurants to keep them up to date with the latest reviews on sites like FourSquare and Yelp. I worked with a great programmer named Sean, who worked mostly on integrating the 3rd-party APIs. It was a Rails app that we pushed to Heroku.

WP Latex Plugin

Posted in Programming on October 18th, 2010 by Jamie – 1 Comment

I’m been brushing up on my LaTex since I’ve been using a lot more math in class, so I installed the WP Latex plugin. Check out this formula for Thin-Plate spline.

  f(x, y) = a_1 + a_x x + a_y y + \sum_{i=0}^p W_i U( || (x_i, y_i) - (x, y) || )

WordPress Plugin Patch: Subscribe2

Posted in Programming on October 8th, 2010 by Jamie – Be the first to comment

I’m working with a network-enabled site, with admin behind SSL. I created a patch for the subscribe2 plugin (Version 6.0) to improve how it worked with the setup. For example, internal links it created were directed to non-https admin pages, which would cause a redirection. Also, assets such as css were not linked via https, causing warnings to appear to people viewing admin pages.

See Github for the patch: http://gist.github.com/617790

Platform:

WordPress 3.0.1
Subscribe2: 6.0

Patch is below as well

--- subscribe2.bak.php	2010-10-08 13:05:14.000000000 -0400
+++ subscribe2.php	2010-10-08 14:39:48.000000000 -0400
@@ -53,30 +53,51 @@
 // start our class
 class s2class {
 // variables and constructor are declared at the end
-
+  function should_use_ssl() {
+    return isset($this->subscribe2_options['use_ssl']) && $this->subscribe2_options['use_ssl'] == 'yes';
+  }
+
+  function get_home() {
+    $opt = get_option('home');
+    return $this->should_use_ssl() ? $this->force_ssl($opt) : $opt;
+  }
+
+  function get_content_url() {
+    $opt = WP_CONTENT_URL;
+    return $this->should_use_ssl() ? $this->force_ssl($opt) : $opt;
+  }
+
+  function get_siteurl() {
+    $opt = get_option('siteurl');
+    return $this->should_use_ssl() ? $this->force_ssl($opt) : $opt;
+  }
+
+  function force_ssl($url) {
+    return preg_replace('/http:/i', 'https:', $url);
+  }
 	/**
 	Load all our strings
 	*/
 	function load_strings() {
 		// adjust the output of Subscribe2 here

-		$this->please_log_in = "<p>" . __('To manage your subscription options please', 'subscribe2') . " <a href=\"" . get_option('siteurl') . "/wp-login.php\">" . __('login', 'subscribe2') . "</a>.</p>";
+		$this->please_log_in = "<p>" . __('To manage your subscription options please', 'subscribe2') . " <a href=\"" . $this->get_siteurl() . "/wp-login.php\">" . __('login', 'subscribe2') . "</a>.</p>";

-		$this->use_profile_admin = "<p>" . __('You may manage your subscription options from your', 'subscribe2') . " <a href=\"" . get_option('siteurl') . "/wp-admin/users.php?page=s2_users\">" . __('profile', 'subscribe2') . "</a>.</p>";
+		$this->use_profile_admin = "<p>" . __('You may manage your subscription options from your', 'subscribe2') . " <a href=\"" . $this->get_siteurl() . "/wp-admin/users.php?page=s2_users\">" . __('profile', 'subscribe2') . "</a>.</p>";
 		if ( $this->s2_mu === true) {
 			global $blog_id, $user_ID;
 			if ( !is_blog_user($blog_id) ) {
 				// if we are on multisite and the user is not a member of this blog change the link
-				$this->use_profile_admin = "<p><a href=\"" . get_option('siteurl') . "/wp-admin/?s2mu_subscribe=" . $blog_id . "\">" . __('Subscribe', 'subscribe2') . "</a>" . __('to email notifications when this blog posts new content', 'subscribe2') . ".</p>";
+				$this->use_profile_admin = "<p><a href=\"" . $this->get_siteurl() . "/wp-admin/?s2mu_subscribe=" . $blog_id . "\">" . __('Subscribe', 'subscribe2') . "</a>" . __('to email notifications when this blog posts new content', 'subscribe2') . ".</p>";
 			}
 		}

-		$this->use_profile_users = "<p>" . __('You may manage your subscription options from your', 'subscribe2') . " <a href=\"" . get_option('siteurl') . "/wp-admin/profile.php?page=s2_users\">" . __('profile', 'subscribe2') . "</a>.</p>";
+		$this->use_profile_users = "<p>" . __('You may manage your subscription options from your', 'subscribe2') . " <a href=\"" . $this->get_siteurl() . "/wp-admin/profile.php?page=s2_users\">" . __('profile', 'subscribe2') . "</a>.</p>";
 		if ( $this->s2_mu === true) {
 			global $blog_id, $user_ID;
 			if ( !is_blog_user($blog_id) ) {
 				// if we are on multisite and the user is not a member of this blog change the link
-				$this->use_profile_users = "<p><a href=\"" . get_option('siteurl') . "/wp-admin/?s2mu_subscribe=" . $blog_id . "\">" . __('Subscribe', 'subscribe2') . "</a>" . __('to email notifications when this blog posts new content', 'subscribe2') . ".</p>";
+				$this->use_profile_users = "<p><a href=\"" . $this->get_siteurl() . "/wp-admin/?s2mu_subscribe=" . $blog_id . "\">" . __('Subscribe', 'subscribe2') . "</a>" . __('to email notifications when this blog posts new content', 'subscribe2') . ".</p>";
 			}
 		}

@@ -142,22 +163,22 @@
 	Hook for Admin Drop Down Icons
 	*/
 	function ozh_s2_icon() {
-		return WP_CONTENT_URL . '/plugins/' . S2DIR . '/include/email_edit.png';
+		return $this->get_content_url . '/plugins/' . S2DIR . '/include/email_edit.png';
 	} // end ozh_s2_icon()

 	/**
 	Insert Javascript into admin_header
 	*/
 	function checkbox_form_js() {
-		wp_enqueue_script('s2_checkbox', WP_CONTENT_URL . '/plugins/' . S2DIR . '/include/s2_checkbox.js', array('jquery'), '1.0');
+		wp_enqueue_script('s2_checkbox', $this->get_content_url . '/plugins/' . S2DIR . '/include/s2_checkbox.js', array('jquery'), '1.0');
 	} //end checkbox_form_js()

 	function user_admin_css() {
-		wp_enqueue_style('s2_user_admin', WP_CONTENT_URL . '/plugins/ '. S2DIR . '/include/s2_user_admin.css', array(), '1.0');
+		wp_enqueue_style('s2_user_admin', $this->get_content_url . '/plugins/ '. S2DIR . '/include/s2_user_admin.css', array(), '1.0');
 	}

 	function option_form_js() {
-		wp_enqueue_script('s2_edit', WP_CONTENT_URL . '/plugins/' . S2DIR . '/include/s2_edit.js', array('jquery'), '1.0');
+		wp_enqueue_script('s2_edit', $this->get_content_url . '/plugins/' . S2DIR . '/include/s2_edit.js', array('jquery'), '1.0');
 	} // end option_form_js()

 /* ===== Install, upgrade, reset ===== */
@@ -301,7 +322,7 @@
 			return;
 		}
 		$string = str_replace("BLOGNAME", html_entity_decode(get_option('blogname'), ENT_QUOTES), $string);
-		$string = str_replace("BLOGLINK", get_option('home'), $string);
+		$string = str_replace("BLOGLINK", $this->get_home(), $string);
 		$string = str_replace("TITLE", stripslashes($this->post_title), $string);
 		$link = "<a href=\"" . $this->permalink . "\">" . $this->permalink . "</a>";
 		$string = str_replace("PERMALINK", $link, $string);
@@ -678,7 +699,7 @@
 		// HASH = md5 hash of email address
 		// ID = user's ID in the subscribe2 table
 		// use home instead of siteurl incase index.php is not in core wordpress directory
-		$link = get_option('home') . "/?s2=";
+		$link = $this->get_home() . "/?s2=";

 		if ( 'add' == $what ) {
 			$link .= '1';
@@ -1384,18 +1405,18 @@
 					switch_to_blog(key($user_blogs));
 				} else {
 					// no longer a member of a blog
-					wp_redirect(get_option('siteurl')); // redirect to front page
+					wp_redirect($this->get_siteurl()); // redirect to front page
 					exit();
 				}
 			}

 			// redirect to profile page
 			if ( current_user_can('manage_options') ) {
-				$url = get_option('siteurl') . '/wp-admin/users.php?page=s2_users';
+				$url = $this->get_siteurl() . '/wp-admin/users.php?page=s2_users';
 				wp_redirect($url);
 				exit();
 			} else {
-				$url = get_option('siteurl') . '/wp-admin/profile.php?page=s2_users';
+				$url = $this->get_siteurl() . '/wp-admin/profile.php?page=s2_users';
 				wp_redirect($url);
 				exit();
 			}
@@ -1585,7 +1606,7 @@

 		$reminderform = false;
 		$urlpath = str_replace("\\", "/", S2PATH);
-		$urlpath = trailingslashit(get_option('siteurl')) . substr($urlpath,strpos($urlpath, "wp-content/"));
+		$urlpath = trailingslashit($this->get_siteurl()) . substr($urlpath,strpos($urlpath, "wp-content/"));
 		if ( isset($_GET['s2page']) ) {
 			$page = (int) $_GET['s2page'];
 		} else {
@@ -1773,7 +1794,7 @@
 				} elseif ( in_array($subscriber, $all_users) ) {
 					echo "</td><td align=\"center\"></td><td align=\"center\"></td>\r\n";
 					echo "<td><span style=\"color:#006600\">&reg;&nbsp;&nbsp;</span><a href=\"mailto:" . $subscriber . "\">" . $subscriber . "</a>\r\n";
-					echo "(<a href=\"" . get_option('siteurl') . "/wp-admin/users.php?page=s2_users&amp;email=" . urlencode($subscriber) . "\">" . __('edit', 'subscribe2') . "</a>)\r\n";
+					echo "(<a href=\"" . $this->get_siteurl() . "/wp-admin/users.php?page=s2_users&amp;email=" . urlencode($subscriber) . "\">" . __('edit', 'subscribe2') . "</a>)\r\n";
 				}
 				echo "</td></tr>\r\n";
 				('alternate' == $alternate) ? $alternate = '' : $alternate = 'alternate';
@@ -1855,6 +1876,9 @@
 					echo "<div id=\"message\" class=\"updated fade\"><p><strong>" . __('Attempt made to resend the Digest Notification email', 'subscribe2') . "</strong></p></div>";
 				}
 			} elseif ( $_POST['submit'] ) {
+			  // security
+			  $this->subscribe2_options['use_ssl'] = $_POST['use_ssl'];
+
 				// BCClimit
 				if ( is_numeric($_POST['bcc']) && $_POST['bcc'] >= 0 ) {
 					$this->subscribe2_options['bcclimit'] = $_POST['bcc'];
@@ -1875,6 +1899,7 @@
 				$this->subscribe2_options['password'] = $_POST['password'];
 				$this->subscribe2_options['private'] = $_POST['private'];
 				$this->subscribe2_options['cron_order'] = $_POST['cron_order'];
+				

 				// send per-post or digest emails
 				$email_freq = $_POST['email_freq'];
@@ -2009,6 +2034,15 @@
 		echo "<input type=\"hidden\" id=\"jspage\" value=\"" . $this->subscribe2_options['s2page'] . "\" />";
 		echo "<input type=\"hidden\" id=\"jsentries\" value=\"" . $this->subscribe2_options['entries'] . "\" />";

+		echo "<h2>" . __('Security Settings', 'subscribe2') . "</h2>\r\n";
+		echo __('Use SSL Links', 'subscribe2') . ': ';
+		echo "<label><input type=\"checkbox\" name=\"use_ssl\" value=\"yes\"";
+		if ( $this->should_use_ssl() ) {
+			echo " checked=\"checked\"";
+		}
+		echo '/> '.__('Forces http links to https for key pages', 'subscribe2');
+
+
 		// settings for outgoing emails
 		echo "<h2>" . __('Notification Settings', 'subscribe2') . "</h2>\r\n";
 		echo __('Restrict the number of recipients per email to (0 for unlimited)', 'subscribe2') . ': ';
@@ -2121,7 +2155,7 @@
 		echo "<h3>" . __('Message substitions', 'subscribe2') . "</h3>\r\n";
 		echo "<dl>";
 		echo "<dt><b>BLOGNAME</b></dt><dd>" . get_option('blogname') . "</dd>\r\n";
-		echo "<dt><b>BLOGLINK</b></dt><dd>" . get_option('home') . "</dd>\r\n";
+		echo "<dt><b>BLOGLINK</b></dt><dd>" . $this->get_home() . "</dd>\r\n";
 		echo "<dt><b>TITLE</b></dt><dd>" . __("the post's title<br />(<i>for per-post emails only</i>)", 'subscribe2') . "</dd>\r\n";
 		echo "<dt><b>POST</b></dt><dd>" . __("the excerpt or the entire post<br />(<i>based on the subscriber's preferences</i>)", 'subscribe2') . "</dd>\r\n";
 		echo "<dt><b>POSTTIME</b></dt><dd>" . __("the excerpt of the post and the time it was posted<br />(<i>for digest emails only</i>)", 'subscribe2') . "</dd>\r\n";
@@ -2449,11 +2483,11 @@
 				$subscribed = get_usermeta($user_ID, $this->get_usermeta_keyname('s2_subscribed'));
 				// if we are subscribed to the current blog display an "unsubscribe" link
 				if ( !empty($subscribed) ) {
-					$unsubscribe_link = get_option('home') . "/wp-admin/?s2mu_unsubscribe=". $blog_id;
+					$unsubscribe_link = $this->get_home() . "/wp-admin/?s2mu_unsubscribe=". $blog_id;
 					echo "<p><a href=\"". $unsubscribe_link ."\" class=\"button\">" . __('Unsubscribe me from this blog', 'subscribe2') . "</a></p>";
 				} else {
 					// else we show a "subscribe" link
-					$subscribe_link = get_option('home') . "/wp-admin/?s2mu_subscribe=". $blog_id;
+					$subscribe_link = $this->get_home() . "/wp-admin/?s2mu_subscribe=". $blog_id;
 					echo "<p><a href=\"". $subscribe_link ."\" class=\"button\">" . __('Subscribe to all categories', 'subscribe2') . "</a></p>";
 				}
 				echo "<h2>" . __('Subscribed Categories on', 'subscribe2') . " " . get_option('blogname') . " </h2>\r\n";
@@ -2514,8 +2548,8 @@
 					$blog['blogname'] = $blogname;
 				}
 				$blog['description'] = get_option('blogdescription');
-				$blog['blogurl'] = get_option('home');
-				$blog['subscribe_page'] = get_option('home') . "/wp-admin/users.php?page=s2_users";
+				$blog['blogurl'] = $this->get_home();
+				$blog['subscribe_page'] = $this->get_home() . "/wp-admin/users.php?page=s2_users";

 				$key = strtolower($blog['blogname'] . "-" . $blog['blog_id']);
 				if ( !empty($subscribed) ) {
@@ -3210,7 +3244,7 @@
 	Function to add js files to admin header
 	*/
 	function widget_s2counter_js() {
-		echo '<script type="text/javascript" src="' . WP_CONTENT_URL . '/plugins/' . S2DIR . '/include/colorpicker/js/colorpicker.js"></script>' . "\r\n";
+		echo '<script type="text/javascript" src="' . $this->get_content_url . '/plugins/' . S2DIR . '/include/colorpicker/js/colorpicker.js"></script>' . "\r\n";
 		echo "<script type=\"text/javascript\">
 			jQuery(document).ready(function() {
 				jQuery('.colorpickerField').focusin(function() {
@@ -3239,7 +3273,7 @@
 	Function to add css files to admin header
 	*/
 	function widget_s2counter_css() {
-		echo '<link rel="stylesheet" href="' . WP_CONTENT_URL . '/plugins/' . S2DIR . '/include/colorpicker/css/colorpicker.css" type="text/css" />' . "\r\n";
+		echo '<link rel="stylesheet" href="' . $this->get_content_url . '/plugins/' . S2DIR . '/include/colorpicker/css/colorpicker.css" type="text/css" />' . "\r\n";
 	} // end widget_s2counter_css

 	function namechange_subscribe2_widget() {
@@ -3274,7 +3308,7 @@
 	*/
 	function add_minimeta() {
 		if ( $this->subscribe2_options['s2page'] != 0 ) {
-			echo "<li><a href=\"" . get_option('siteurl') . "/?page_id=" . $this->subscribe2_options['s2page'] . "\">" . __('[Un]Subscribe to Posts', 'subscribe2') . "</a></li>\r\n";
+			echo "<li><a href=\"" . $this->get_siteurl() . "/?page_id=" . $this->subscribe2_options['s2page'] . "\">" . __('[Un]Subscribe to Posts', 'subscribe2') . "</a></li>\r\n";
 		}
 	} // end add_minimeta()

@@ -3291,7 +3325,7 @@
 			add_filter('mce_buttons', array(&$this, 'mce3_button'));
 		} else {
 			buttonsnap_separator();
-			buttonsnap_jsbutton(WP_CONTENT_URL . '/plugins/' . S2DIR . '/include/s2_button.png', __('Subscribe2', 'subscribe2'), 's2_insert_token();');
+			buttonsnap_jsbutton($this->get_content_url . '/plugins/' . S2DIR . '/include/s2_button.png', __('Subscribe2', 'subscribe2'), 's2_insert_token();');
 		}
 	} // end button_init()

@@ -3299,7 +3333,7 @@
 	Add buttons for WordPress 2.5+ using built in hooks
 	*/
 	function mce3_plugin($arr) {
-		$path = WP_CONTENT_URL . '/plugins/' . S2DIR . '/tinymce3/editor_plugin.js';
+		$path = $this->get_content_url . '/plugins/' . S2DIR . '/tinymce3/editor_plugin.js';
 		$arr['subscribe2'] = $path;
 		return $arr;
 	}
@@ -3699,4 +3733,4 @@
 	var $options_saved = '';
 	var $options_reset = '';
 } // end class subscribe2
-?>
\ No newline at end of file
+?>

Local Maxima in Edge Detection

Posted in Software on September 22nd, 2010 by Jamie – 1 Comment

I’ve been working on some homework for computer vision. It’s such an interesting class because of how rich the visualization of my code results can be. Matlab has also been a real pleasure to work with. Everything is well documented and the IDE has features I haven’t seen in other IDEs. I am working on an assignment in edge detection.

There are several steps required including performing a convolution of the image with with the derivative of the Gaussian, determining the magnitude of the gradient, and using it to find local maxima (in terms of intensity) of the image. That’s the part I’m at right now. Instead of using the x and y components of the gradient to compute edge orientation, I just determine local maxima by querying all the pixel neighbors of each pixel. This was quicker and helped me to make sure my code worked. Here’s the magnitude of the gradient of the image and the local maxima as computed by my algorithm. They’re very bad points for edge detection, but I’m happy I get something resembling the shapes of the image! One step at a time.

Matlab’s Image Edge Detection

Posted in Software on September 9th, 2010 by Jamie – Be the first to comment

I’ve been doing some homework for Computer Vision class. Matlab apparently has extensive image processing capabilities. One handy function is “edge” which will return a zero-filled matrix with 1s corresponding to edges.

The picture shows the results of using various types of edge detection.

From left to right, top to bottom, the methods of edge detection are: Sobel, Prewitt, Laplacian of Gaussian, Canny, Roberts, and Zero-cross


Switch to our mobile site