Posts tagged “programming”
Kip

How to programmatically update your Twitter status using OAuth in PHP

Written by Kip on Thursday, August 12, 2010 at 10:22 pm (EDT)
Tagged as:

Earlier this week I was informed that Twitter will soon be ending its support for “BasicAuth” in the Twitter API, in favor of OAuth authentication. This affects me because I use the API to automatically post a “just blogged!” link to Twitter after every new blog post. Using BasicAuth, this was super simple:

1
2
3
4
5
6
7
8
9
10
11
function postStatus($status, $username, $password)
{
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, 'http://www.twitter.com/statuses/update.xml');
  curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, 'status=' . urlencode($status));
  curl_setopt($ch, CURLOPT_USERPWD, $username . ':' . $password);
  
  return curl_exec($ch);
}

OAuth is a little more complicated, but I got it to work after about four or five hours of banging away it with the help of this article.1 Since I couldn’t find anywhere that this was described in detail, I decided I would document the whole process here on my blog. I don’t claim that this code is great, but it gets the job done. If you couldn’t care less about the workings of OAuth, and just want a give-me-teh-codez solution, then this is for you.

The first thing you have to do is register a new app. This sounds scary but it’s actually very easy. When filling out the form, note the following fields:

  • Application Name: this is what will show up under your tweets. In my case, I chose “vacantnebula.com” since all tweets from my app are announcements of new posts on this site.

  • Application Website: this is the URL that application name will link to.

  • Application Type: I’m not sure if it matters, but I chose “client”.

  • Default Access Type: you must select “read & write” to be able to update status (i.e. “write”).

After registering your application, you can view application details. Here you will see your consumer key and your consumer secret. You will need these keys later.

For a single-user application (which is what I’m describing), you will need to click on my access token. This will give you the access token (oauth_token) and access token secret (oauth_token_secret). Again, you will need these later.

And without further ado, here is the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<?php

class twitter
{
  //FILL IN THESE VALUES!!
  private $consumerKey      = '???';
  private $consumerSecret   = '???';
  private $oauthToken       = '???';
  private $oauthTokenSecret = '???';
  
  /**
   * Posts status to a twitter account. Returns true if successful, result
   * of curl_getinfo() if failure. 
   */ 
  function postStatus($status)
  {
    return $this->apiCall('https://api.twitter.com/1/statuses/update.xml', array('status'=>$status));
  }
  
  //separate function to leave the door open to other API calls...
  private function apiCall($url, $params)
  {
    $method = 'POST';
    
    //postString covers what will *actually* be posted
    $postString = $this->joinParams($params);
    
    //now adding to $params other OAuth properties...
    $params['oauth_nonce']            = sha1(time() . mt_rand());
    $params['oauth_timestamp']        = time();
    $params['oauth_signature_method'] = 'HMAC-SHA1';
    $params['oauth_version']          = '1.0';
    $params['oauth_consumer_key']     = $this->consumerKey;
    $params['oauth_token']            = $this->oauthToken;
    
    ksort($params); //IMPORTANT!
    $paramString = $this->joinParams($params);
    
    $signatureBaseString = $method . '&' . rawurlencode($url) . '&' . rawurlencode($paramString);
    $signatureKey = $this->consumerSecret . '&' . $this->oauthTokenSecret;
    $params['oauth_signature'] = base64_encode(hash_hmac('sha1', $signatureBaseString, $signatureKey, true));
    
    $authHeader = 'Authorization: OAuth realm=""';
    foreach($params as $key => $val)
      $authHeader .= ", $key=\"" . rawurlencode($val) . "\"";
    
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postString);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //required for HTTPS URL
    curl_setopt($ch, CURLOPT_HTTPHEADER, array($authHeader));
    
    $content = curl_exec($ch);
    $resultInfo = curl_getinfo($ch);
    curl_close($ch);
    
    if ($resultInfo['http_code'] == 200)
      return true;
    
    $resultInfo['content'] = $content;
    return $resultInfo;
  }
  
  //Join key/value pairs together in url string format, encoding values.
  private function joinParams($params)
  {
    $paramString = '';
    foreach($params as $key => $val)
    {
      if($paramString !== '')
        $paramString .= '&';
      $paramString .= $key . '=' . rawurlencode($val);
    }
    return $paramString;
  }
}

And I assume you know this, but to use the API it’d look like this:

1
2
$twitter = new twitter();
$result = $twitter->postStatus('hello world!');
1 I could have saved myself over an hour by realizing that I had to call rawurlencode rather than urlencode; the former encodes spaces as %20, whereas the latter encodes them as +.
Kip

QuickReplace

Written by Kip on Sunday, August 1, 2010 at 4:55 pm (EDT)
Tagged as:

It’s amazing how often, as a programmer, I find myself pasting something into Notepad, then pressing Down, Home, Ctrl+V, over and over and over. (Or a variant, like Down/End/Ctrl+V, or End/Comma/Delete, or F3/Ctrl+V/Enter, etc.) It gets very tedious, and sometimes requires me to write an adhoc Perl script to do it. Yesterday I had the idea to finally just take a few hours to write a simple tool that I should have written years ago.

I give you: QuickReplace

It’s really simple. Just paste text into the first big text area, and then it will be filtered and displayed in the lower text area. There are three types of filters: text that is prepended or appended to each line; a simple search/replace (with \n and \t allowed), and a full-on regex substitution. And everything is updated as you type it, so you can see the effects of the filters as you enter them. (This really helps when you haven’t written a regex in a month or so.)

Everything is done in Javascript so the page is completely self-contained—you can view source and save a local copy if you wish. (It does require an internet connection, as it uses Google-hosted jQuery.) It’s also kind of a work in progress that might at any time be edited on the fly. Consider yourself warned.

No Comments | Add Comment
Kip

New and improved gradient generator. Now almost as good as Photoshop!

Written by Kip on Wednesday, July 7, 2010 at 10:00 pm (EDT)
Tagged as:

You may recall that the gradients I use on this site (in the background images on the photos pages, and in the header above each comment) are dynamically generated. I made some significant improvements to the code over the holiday weekend, which I will discuss here.

First, the minor things. I’ve added support for If-Modified-Since header, so that no cached image is retrieve and no content is returned to the browser if the user has the image cached. In doing this I learned that PHP’s filectime does not actually return the time the file was created; rather, it returns the last time it was changed. I don’t really understand the difference between this and filemtime (time the file was modified), as they both seem to always return the same time. Oh well.

Next, I added support for 3-character colors (like 000 for black and f00 for red). This just makes sense if you’re used to dealing with them in CSS.

And finally, the big improvement is an implementation of error diffusion.1 Why did I need to do this? In some very gradual gradients, you would see bands of individual colors. Eight bits per channel just isn’t quite enough.  For example, look at this gradient from 0x888888 to 0x444444:

Gradient from 0x888888 to 0x444444, with no dithering

You should be able to see vertical bands somewhere in that gradient. If not, it probably has to do with your monitor’s gamma settings or something. In any case, what I do to prevent this is keep a running sum of how far off each pixel is from its “true” color. When the absolute value of that sum is greater than 1, I adjust the color of the next pixel by one level in the appropriate direction to compensate. This gives a much smoother gradient:

Gradient from 0x888888 to 0x444444, with no dithering

This actually gives better results than Paint.NET and Paint Shop Pro. Here’s a close-up look at what that looks like, with pixel colors exaggerated:

Close-up of gradient with dithering

It’s good, though it’s not quite as good as what you get in Photoshop:

Close-up of gradient generated in Photoshop

Clearly the Photoshop guys are doing some kind of subpixel shading, since there are slightly colored pixels in a monochrome gradient. I guess they know what they’re doing.

Lastly, here is my PHP gradient generator source code, if you want to look under the covers and/or utilize the code.

1 Technically, it’s what I thought error diffusion was. But I read the Wikipedia article on error diffusion when writing this post, and now I’m pretty sure that what I did isn’t actually error diffusion. It’s kind of a similar process that I came up with all on my own.
No Comments | Add Comment
Kip

Album Thumbnail PHP class

Written by Kip on Tuesday, April 6, 2010 at 8:49 pm (EDT)
Tagged as:

You may have noticed that the thumbnails for albums on our photos page are each little collages. Here are some examples:

Well as of today I’ve received three requests for the code behind these images, so I figured it was time to write up a proper blog post about the it. I mentioned the code in 2006, and that it was inspired by this article from A List Apart. I took their idea and came up with several more layouts to use, and some code to generate the thumbnail from dynamic layouts.

The class takes four image files as input, and generates a thumbnail for them. It does have the annoyance that the generated images have varying heights. I’ve thought about writing a fancy “2.0” version of the code, using Javascript to position/crop/scale the images, then use PHP to render the final result. But who knows if I’ll ever get around to it.

For now, I’ll just show you how it’s used. It’s very easy:

1
2
3
4
5
6
7
$at = new album_thumbnail();
$at->add_image('/images/001.jpg');
$at->add_image('/images/002.jpg');
$at->add_image('/images/003.jpg');
$at->add_image('/images/004.jpg');

$at->make_thumbnail('/images/thumb1234.jpg');

On my admin page, I initially pick four images at random from a given directory. I can then try again with four more images, or specify to keep some of the images and pick random images for the others, or I can specify the ids of all the images I want to be used. That part is left as an exercise for the reader. Without further ado...

View the source code here.

Kip

ImageSizer

Written by Kip on Friday, June 19, 2009 at 12:10 am (EDT)
Tagged as:

I wrote a program last week for resizing images so that they can fit onto a two-monitor desktop, and I figured I’d share with the world before heading to the beach.  This program does more than just resize an image, though.  It accounts for the gap between the two monitors, so that it looks much more like you are looking through the monitors.  Most of this post will consist of an explanation of what exactly that means and why you’d want to do it.

Okay, for starters let’s say you have two monitors sitting side-by-side.  In our example, these monitors each have a resolution of 304×228 pixels, giving a resolution of 608×228 for the entire desktop.  Here is what that looks like:1

Blank two-monitor example

Now, let’s say you want to use this photo of the Gizah pyramids by Ricardo Liberato, the #21 finalist for Wikimedia Commons Picture of the Year 2007, as your wallpaper.  Here is what the photo looks like initially:

A great photo of the Gizah pyramids

There is a problem here, because that’s not the right proportion, so you’d want to crop out a portion of the image that is the right proportion.  Here is a cropped portion that is the proper ratio and size (608×228):

The Gizah pyramids photo, resized to 608×228

Now, let’s use that image as our desktop wallpaper on our dual-monitor setup:

The Gizah pyramids stretched across a two-monitor setup

I don’t know about you, but I find this very aesthetically displeasing.  Suddenly the pyramid is not shaped like a pyramid anymore!  Your mind expects the image to continue through the space between the monitors, but it actually just picks up where it left off on the edge of the other screen.  In fact, it kinda makes it look like there is a fourth, smaller pyramid, between the first and second one.

So here’s where my app comes in.  We need to figure out how wide that gap is, in pixels.  If you knew the dpi of your monitor, you could measure the gap in inches and calculate the number of pixels.  But if you don’t know that, here’s how I measure it.  Open up any kind of image editing app (Paint will do just fine).  Place the window so that it straddles the gap between monitors.  Draw a 45-degree line that spans the monitors.  It is very important that the line be exactly 45 degrees (you can hold control or shift or something to fix the line to 45 degrees in most image editing apps).  Now, hold something with a straight edge (say, a piece of paper) so that it lines up with the line on one monitor.  Holding the straight edge there, click somewhere on the other monitor, where the line would be if it was accounting for the gap, and draw another 45-degree line starting from there.  Now measure the vertical distance, in pixels, between the two lines.  This will be equivalent to the horizontal distance, in pixels, between the two monitors.  For our example, here is what that might look like:

Example of measuring gap between monitors

You can see the solid black line is “straight” if the gap is not accounted for.  However, the dashed line shows how the line would behave if the gap was considered to have a width.  The distance between the dashed line and the solid line on the right-hand monitor is 50 pixels, so that is the width of our gap.  So now, let’s use my app:

1
java -jar ImageSizer.jar pyramids.jpg -monitorWidth 304 -height 228 -gap 50

This will generate pyramids.resized.png, which looks like this:

Gizah pyramids resized by tool, accounting for gap

When we use this image as our desktop wallpaper, we get an image that looks correct:

The Gizah pyramids stretched across a two-monitor setup, accounting for the gap between the monitors

If you’d like the program, you can download it right here.  But before you use it, here are a few things you should know:

  • You may get OutOfMemory exceptions on very large images.  If this happens (thanks Peter), you can increase the Java heap size from the command line like this:
        java -Xmx256m -jar ImageSizer.jar ....
    If that still doesn’t work, increase the 256 to a bigger number.  It is important that the -Xmx parameter comes before the -jar parameter, so that Java knows it is a parameter to the JVM and not to the ImageSizer.

  • When the image is not the proper proportion (which will be nearly all the time), it will crop from the middle of the image.  In many cases, this will be a less-than-ideal cropping.  If that happens, you should crop the image the way you want it cropped first.  (The tool will still help you out because removing the middle of an image is much more tedious.)

  • Your monitors must be of equal resolution.

  • Supported file types are .jpg, .png, and (I think) .bmp and .gif.  (I’ve only tested jpg and png myself though.)

  • Output file will always be .png format, even if a different extension is used on output file.  This is important because a lossy compression can cause some pixels to “bleed” between the monitors.

  • There is only support for two-monitor setups.

  • If you want to modify the code, feel free to do so.  You can even redistribute if you want, just be sure to leave my name and URL in the comments and help info.  The source is included in the jar file (open it as a zip file).  There are only two Java files.

  • There is a good chance there are some bugs, as this was written in two evenings, with a fourteen-month-old competing with the computer for my attention.  The vast majority of that time was spent trying to figure out how to use the Java image libraries.  I probably could have written this in PHP in an hour, but I didn’t want to use PHP from the command line, and I didn’t want to have to upload large images.

1 yes, these monitor images are stolen from Windows XP display settings
Kip

Why you shouldn’t put new columns in the middle of a table

Written by Kip on Tuesday, June 9, 2009 at 9:30 am (EDT)
Tagged as:

I learned something new about databases this week.  Perhaps I should have already known this, but it surprised me, so I have decided to share with the small segment of the world that reads this blog.  In the past, I’ve always done database table management (i.e. creating/dropping tables or columns) through a GUI (like Management Studio for SQL Server, or phpMyAdmin for MySQL).  In these tools, it is very easy to insert a new column in the middle of a table, and it never occurred to me that this was a big operation.  This week, I had to write a script that would perform my changes to a table on a customer database.  It turns out that the only way to put add a new column to the middle of a table1 is to:

  1. Create a temporary table, with the columns in the order you want.

  2. Insert everything from your original table into the new table.

  3. Drop the original table.

  4. Rename the temporary table to the name of the original table.

  5. Recreate any indexes and constraints that existed on the original table.

On a very large table, this is quite a lengthy operation!  But if you just add the new column to the end of the table, you can do that in a single SQL statement, and it runs quite quickly.  And the fact is that if your code relies on the columns being in a particular order, you are doing something wrong.  (Fortunately, I knew enough that I got that part right.)

1 At least in SQL Server, and from what I’ve read this appears to be true in all other RDBMSs
No Comments
Kip

Free code giveaway

Written by Kip on Saturday, March 21, 2009 at 11:26 pm (EDT)
Tagged as:

I added some code to the site to improve the way source code is displayed, both in snippets in my blog and when viewing an entire file directly.  I’m adding line numbers on the server-side, but they are in a separate div so you won’t end up copying the line numbers if you copy and paste the code.  The syntax highlighting is all done in Javascript by prettify, an open-source library provided by Google.  After getting around two annoying jQuery bugs (one which is only present on IE6, and another which was fixed by upgrading to the latest jQuery level) I got it up and running, and it looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
  /**
   * Returns 1/this.
   * 
   * @throws ArithemeticException if this == 0.
   */
  public BigFraction reciprocal()
  {
    if(numerator.equals(BigInteger.ZERO))
      throw new ArithmeticException("Divide by zero: reciprocal of zero.");
    
    return new BigFraction(denominator, numerator, true);
  }

Anyway, I figured I’d show off the full-file view with some source code you’re free to use if you want to.  You can find the BigFraction class I wrote in Java when working on some Project Euler problems.  The class represents a fraction as a ratio of two BigIntegers, so it will never overflow, and there will never be roundoff error.  It was fun to write, because it involved lots of math and manipulation of base-2 numbers (especially for the constructors which took one or two double variables), and I’m one of those weirdos who really likes those things.  This works in all the Project Euler problems I’ve used it in, and I’ve done some pretty exhaustive ad-hoc testing, but there’s still a good chance I’ve missed a bug or two.  Especially since I didn’t bother writing any unit tests or anything (hey, this is spare-time coding!).  If you use this and happen to find any bugs, let me know.  And of course, I need to close with:

Disclaimer: the BigFraction class is provided as-is with no warranty expressed or implied.  If you use it to calculate missile trajectories and end up nuking the wrong city, you shouldn’t come whining to me.

No Comments | Add Comment
Kip

New site feature: searching

Written by Kip on Tuesday, March 17, 2009 at 4:02 am (EDT)
Tagged as:

I finally got around to implementing a search feature on this site.  If you search for something in the bar over on the right side of the page, you’ll get a search over all the blog posts, photo, and photo albums on this site.

I did all this with the Zend Framework’s PHP implementation of Lucene.  It seems to give good results very quickly, although there are some issues I’m having that are either misunderstandings or outright bugs.  Or maybe it’s because I’ve been up till 4am fiddling with this thing.  Tomorrow I’ll try to simplify my scenario and see if I still get the same results... if not, then I guess I need to figure out where I’ve missed something.  I’ve found that the way you design a search index is quite a bit different from the way you work with a relational database, mainly because you intentionally denormalize data for the sake of faster searching, when you wouldn’t do that for a relational database (at least not until you found that some particular JOIN or something was a huge bottleneck).

Anyway, I need to get some sleep.  If you try out my search box and notice something particularly odd, let me know.  (Well, something other than the styling, which isn’t fully presentable yet.)  Most of the problems I’m having are with more advanced queries that aren’t working the way the documentation claims they should, but it shouldn’t be anything most users would ever see.

Update:  I figured out what was wrong, it was due to using the default query parser, when I needed to construct the query from APIs.  After writing my own query processor, all is well.  More info about the specific problem I was having can be found on this Stack Overflow question, which pointed me in the right direction.

No Comments
Kip

Some thoughts on programming style

Written by Kip on Tuesday, February 3, 2009 at 2:02 pm (EST)
Tagged as:

Time to discuss something controversial that leads many geeks to commit acts of heinous violence.  I’m talking about programming style!

So there are three basic ways to write if/elseif/else statements in most languages with C-like syntax:

Style A

1
2
3
4
5
6
if(condition1)
  statement1;
else if (condition2)
  statement2;
else
  statement3;

Style B

1
2
3
4
5
6
7
if(condition1) {
  statement1;
} else if (condition2) {
  statement2;
} else {
  statement3;
}

Style C

1
2
3
4
5
6
7
8
9
10
11
12
if(condition1)
{
  statement1;
}
else if (condition2)
{
  statement2;
}
else
{
  statement3;
}

Personally, I go for the most readable and maintainable code, so I use Style A iff all conditions and statements are trivial (by which I mean, they are short and fit on one line).  Otherwise I use Style C.  (Which you can see, for example, in that gradient-generator source I posted a few weeks ago.)

I’ve posted on my preference for Style C over Style B before, and I’m not going to focus too much on that here today.  However, I continue to see Style B promoted as the universal, be-all end-all solution.  It is recommended by Sun for Java, and by Zend for PHP.

The argument for preferring Style B over Style A usually goes something like this:

What if you come along and add a new line?

1
2
3
4
5
if(condition1)
  statement1;
else
  System.out.println("Condition1 failed!");
  statement2;

Now statement2 gets executed everytime!

The argument makes sense from an academic standpoint, but I am pretty sure this almost never ever happens in practice.  The reason for this is that anyone who has been programming for more than a month will immediately see that this code won’t work as designed.  It is a glaring bug that jumps out at you.  It is nearly impossible to overlook!  (Again, this is all assuming that the conditions and statements are all trivial.)

Now, for the last four and a half years my job has been primarily to fix bugs in a huge body of code, very little of which was written by me.  For the last two and a half years, in particular, I’ve been the guy who looks at build traces and unit test results from the previous night.  And when there are build or test errors, I have to look at recently changed code and decide who is responsible.  This means I have seen most of the errors made by a group of about fifty or so programmers.  That is to say, real-world errors made by real programmers, not hypothetical errors that might be made by a theoretical programmer.  So I think I am reasonably well-qualified to have a strong opinion on the matter.

With that in mind, I’ve never seen an error that was due to the use of Style A for trivial statements.  I have seen some downright ugly code that used Style A inappropriately, with conditions that were ten lines long.  And I’ve seen ugly code that has braces on the if block but not the else block (or vice-versa).  And I have seen several errors in Style B or Style C that result from intermingling of tabs and spaces.  This happens because simple editors like vi and Notepad render tabs that are up to 8 characters wide (per spec, I might add), but advanced editors usually break spec in favor of user-friendliness, rendering tabs at 2 or 4 characters wide (or whatever the user sets them to).  So if code was written using 4-character tabs in Visual Studio, then new code is added by someone using spaces in vi, and this happens back and forth a few times, you get indentation that jumps all over the place.  This is where I think Style C is better than Style B, because it is easier to find the matching open-brace because usually the opening and closing braces are written by the same developer with the same indentation level, even if the code between the braces jumps all around.  Also, with Style B, at a glance the code looks like indentation is wacky, since you have to actually read the previous line (or scan to the right end of the previous line) to find out if the developer actually intended the indentation to increase there, or if someone just increased indentation because they were using a different editor.

You can tell me why you disagree with me, and I am fully aware that there will never be agreement on this point; however, I’ll continue to avoid Style B until my pay is docked for it.  Someone has to stand up for what is right.

Kip

Gradient update

Written by Kip on Saturday, January 17, 2009 at 1:25 pm (EST)
Tagged as:

If anyone decided to make use of the gradient generator code I posted yesterday, be advised that I just added alpha channel (i.e. transparency) support.  I’ve updated the source code to include these new changes.

Something strange I found out is that PHP only supports a 7-bit alpha channel, even though PNG (and really any image format supporting transparency) uses the same number of bits for the alpha channel as for the red, green, and blue1.  I’m assuming this is because PHP uses 32-bit signed integers, and if they let the alpha channel use all 8 remaining bits they would use the sign bit.  And heaven forbid people need to know a little bit about twos-complement.  Oh well.

And of course, if you use transparent PNGs, you should know they are not supported by IE6.  But I’m guessing any IE6 users out there are becoming increasingly aware of the fact that a lot of sites look strange for them.

1 Unless it is like GIF and only uses a 1-bit alpha channel
No Comments
RSS feeds: Kip's - Stephanie's - Both
Admin