Uploading a Photo with the Facebook Android SDK

Facebook’s example code for Android shows how to upload a photo using the REST API rather than the newer Graph API. I knew that the iOS SDK can handle it via Graph just fine, so I changed the code in my Android app to use Graph as well (also since doing it with REST wasn’t working). I’ve added a quick method for uploading a picture below, hopefully it works since it was modified from the original and thus untested. It runs synchronously, so you will want to run this in a separate thread (or else convert it to the Async API – in my app it was just easier to make it multithreaded).

public static String uploadPhoto(Facebook facebook, Bitmap image,
        String albumId)
{
    if ( albumId == null ) {
        albumId = "me";
    }

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    image.compress(CompressFormat.JPEG, 75, bos);
    byte[] photoBytes = bos.toByteArray();

    Bundle params = new Bundle();
    params.putByteArray("picture", photoBytes);

    try {
        String resp = facebook.request(albumId + "/photos", params, "POST");
        JSONObject json = Util.parseJson(resp);
		return json.getString("id");
    } catch ( IOException e ) {
    } catch ( FacebookError e ) {
    } catch ( JSONException e ) {
    }

    return null;
}
Posted in Java | Tagged , | Leave a comment

Ugly Old RPG Code

Here’s an example of my past, and how bad I used to be at application design. I started this RPG back in 2006 and eventually stopped making it at the end of 2008. It sort of works… well, it would if it included a DB dump (or install script) and you had a vBulletin installation to hook it into. I’ve apparently lost the latest copy, which included the beginning of a status effect editor, so that feature is missing.

Beginning coders should probably not study this as an example, though I will admit I did some neat algorithms, and the ajax-ified equip screen and battle system are cool.

http://crindigo.com/stuff/rpg-0.5.0.zip

Posted in PHP | Tagged , | Leave a comment

Exception Thrown Without a Stack Frame and Sessions

Just a note, if anyone receives this error at the bottom of the page when programming in PHP, and you’ve checked things like throwing exceptions inside of exception handlers, check any objects you’re storing in $_SESSION. If an exception is thrown when the session mechanism serializes your objects (usually at the very end of a request), it will be outside of the regular code flow and will spit out an error at the very end of your output.

So, if this applies to you, make sure you do not attempt to serialize properties that cannot be serialized, using __sleep to limit the properties. Then, define a __wakeup to reconstruct those properties if necessary.

Ref: http://www.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.sleep

Posted in PHP | Leave a comment

PHP Shell Execution Reminder

If you are using PHP to execute a custom-written shell script, keep in mind that the $PATH for the web server’s user can be different than the user account you’re using to execute it. Meaning, if it doesn’t behave properly, try using full paths to programs. For example, when writing a shell script to generate thumbnails for JPGs in a directory:

cd $1
for i in `ls | egrep -i '\.jpg$'`; do
    /usr/local/bin/convert $i -thumbnail $2x$3 thumb_$i
done

Just using “convert” rather than “/usr/local/bin/convert” doesn’t work, since /usr/local/bin is not part of $PATH for the web server.

Posted in PHP | Tagged , | Leave a comment

Canvas Cake

For fun, and Jeremy’s birthday, I redid my PHP/GD cake in HTML5 Canvas. This version also sports animated candlelight.

Cake!

Posted in JavaScript | Tagged | Leave a comment

Ancient Image Class

This is a really old image library/class thing I wrote back in Summer 2006 while working with Jeremy and his company. I believe it was originally written in PHP4 and updated to PHP5 a month or two after the original was written. There are some features, like drawing rotated images/ellipses, that were commented away due to them not working on PHP4, but may work now if someone dares to try. ;) The comments are fairly plentiful, and I’m feeling lazy, so it shouldn’t need a manual to get started (besides, I haven’t used it in years either).

The code is located at http://gist.github.com/429474

Posted in PHP | Tagged | 1 Comment

Wildfire Log Adapter for Solar

While doing some more development for Crindigan, I figured I should be looking for a better way to show debug information than putting it in the page footer, so I looked at FirePHP. Unfortunately the Firephp log adapter in Solar was out of date, so I wrote a quick adapter that uses the newer Wildfire protocol.

/**
 * Log adapter that works with the latest FirePHP version
 * (probably not FireConsole though, whenever it's released).
 *
 * @package Crindigan
 * @author Steven Harris
 * @license http://opensource.org/licenses/bsd-license.php BSD
 * @version $Id$
 */
class Rpg_Log_Adapter_Wildfire extends Solar_Log_Adapter {

    /**
     * Default configuration values.
     *
     * @config string|array events The event types this instance
     *   should recognize; a comma-separated string of events, or
     *   a sequential array.  Default is all events ('*').
     *
     * @config dependency response A Solar_Http_Response dependency injection.
     *
     * @var array
     *
     */
    protected $_Rpg_Log_Adapter_Wildfire = array(
        'events'   => '*',
        'response' => 'response',
    );

    /**
     * The Solar_Http_Response where headers will be sent.
     *
     * @var Solar_Http_Response
     */
    protected $_response;

    /**
     * The Solar_Json instance used to encode JSON for Wildfire.
     *
     * @var Solar_Json
     */
    protected $_json;

    /**
     * Wildfire header index to keep headers in sequential order.
     *
     * @var int
     */
    protected $_index = 0;

    /**
     * Post-construction tasks. Sets up the response, JSON, and default Wildfire headers.
     */
    protected function _postConstruct() {
        parent::_postConstruct();

        $this->_response = Solar::dependency('Solar_Http_Response', $this->_config['response']);

        $this->_json = Solar::factory('Solar_Json');

		$this->_response->setHeader('X-Wf-Protocol-1', 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2');
        $this->_response->setHeader('X-Wf-1-Plugin-1', 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3');
        $this->_response->setHeader('X-Wf-1-Structure-1', 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1');
    }

    /**
     * Writes the log message to FirePHP.
     *
     * @param  string $class Class name.
     * @param  string $event Event name.
     * @param  mixed  $descr Log data. Any data type should work, assuming it can be encoded as JSON.
     * @return bool Always true.
     */
    protected function _save($class, $event, $descr) {
    	$meta = array();
    	$meta['Type']  = 'LOG';
    	$meta['Label'] = "$class-$event";

    	$data = $this->_json->encode(array($meta, $descr));
    	$len  = strlen($data);

		if ( strlen($data) <= 4990 ) {
			$this->_index++;
			$this->_response->setHeader("X-Wf-1-1-1-{$this->_index}", "$len|$data|");
		} else {
			$chunks = chunk_split($data, 4990, "\n");
			$parts = explode("\n", $chunks);
            $num_parts = count($parts);
            for ( $i = 0; $i < $num_parts; $i++ ) {
				$this->_index++;
				$this->_response->setHeader("X-Wf-1-1-1-{$this->_index}",
					($i == 0 ? $len : '') . "|{$parts[$i]}|" . (($i == $num_parts - 1) ? '' : '\\'));
            }
        }

        return true;
    }
}
Posted in PHP | Tagged , | Leave a comment

Pwiff Update

I just committed a simple Movie and Encoder class, so making a blank movie is now far easier to understand. At least now you don’t have to calculate the file length by hand. :-P

$env = new Pwiff_Environment;
$env->setSwfVersion(10);

$movie = new Pwiff_Movie($env);
$movie->setFrameSize(100, 100);
$movie->setFrameRate(0);

$enc = new Pwiff_Encoder($movie, new Pwiff_Output_File('test.swf'));
$enc->encode();

The first step is to define an environment, which creates a context for encoding (and later decoding). By setting the version, certain tags or tag attributes could be ignored when reading or writing, if they are in a higher version than what you set. Then, you define a movie object, and set some of its properties, like the frame size and frame rate. After that, you would do more fancy things (when they get written, though you can addTag() with it right now). Finally, set up an encoder, passing the movie and output objects, and call encode(), which will write it with the given output instance (in this case, to the file test.swf).

Posted in PHP | Tagged , | Leave a comment

Pwiff Source Released

Today, I was able to get Pwiff to create a “blank” SWF file, meaning a header, a FileAttributes tag, and an End tag. As a result, I decided to start a Google Code project for it, and host the files there instead of my private subversion location. It’s very bare bones right now, as you can see from the following example that created the 25-byte file:

$env = new Pwiff_Environment;
$env->setSwfVersion(10);

$out = new Pwiff_Output_File('test.swf');

$h = new Pwiff_Record_Header(false, 10, 25, new Pwiff_Record_Rect(0, 100, 0, 100), 0, 0);
$f = new Pwiff_Tag_FileAttributes($env);
$e = new Pwiff_Tag_End($env);

$h->write($out);
$f->write($out);
$e->write($out);

So yeah, it definitely needs some helper classes to be easier to use. :-P Right now it’s pretty much just raw record/tag classes. The resulting SWF file is located here.

Pwiff @ Google Code
Pwiff @ Ohloh

Posted in PHP | Tagged , | Leave a comment

NextShout is now Free

NextShout was a commercial shoutbox product I released two or three years ago, for the vBulletin forum software. Its bandwidth consumption is far lower than any competing products, due to its use of efficient JSON and only sending information deltas, rather than completely refreshing entire blocks of HTML. Other features include a modular command system, multiple channels, automatic pruning and logging (configurable per channel), and new post/thread notices. It requires PHP 5.1.4, and at least vBulletin 3.6.9 (currently unavailable for 4.x).

Find more information and the download at its website.

Posted in PHP | Tagged | Leave a comment