How I made a Tweetie 2 Image Service

Recently, Gandi offered .im domains cheap and, being of puerile mind, I picked up myqu.im for a laugh. I put a jokey wordpress blog on there and called it My Quick Images. The joke was that anyone finding it would assume the site was designed without knowing Quim was an obscene word. Much hilarity ensued and it even made the B3ta newsletter.

The joke stopped being funny when Tweetie 2 came out for the iPhone and it allowed you to add custom image services. I took that as a challenge and assumed I could rip lots of functionality from my URL shortener, tw3.it and have something working in under a day. As it turned out, it was remarkably simple to get the basics up and running. All the code is below. Files may need fixing thanks to WordPress not being the best code repository.

The URL to POST to is http://myqu.im/u and it does exactly what the docs say to do. Oh, and if you don’t want it to return an image, you can add a trailing slash like http://myqu.im/u/ and it will return an HTML page instead.

If you notice anything like stupid cock-ups in my code, which isn’t unlikely in this early stage, please feel free to point it out in the comments. I’m not really a coder, so it’d not surprise me to find out I’ve made a massive oopsie.

Here are the settings for Tweetie 2 to use myqu.im:

Tweetie 2 settings for myqu.im

Here are the settings for Tweetie 2 to use tw3.it:

Tweetie 2 settings for tw3.it

< ?php
include "db.inc.php";
include "functions.inc.php";
foreach ($_POST as $key => $value) {
    $_POST[$key] = mysql_real_escape_string($value);
  }   
?>

< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


	
	posted
	


< ?php
$filename=basename($_FILES['media']['name']);
$extension = getExtension($filename);
$extension = strtolower($extension);
if (($extension != "jpg") && ($extension != "jpeg") && ($extension != "png") && ($extension != "gif")) 
	{
	//print error message
	echo '

Unknown extension!'; } else { if ($extension == "jpg") { $mime = "image/jpeg"; } if ($extension == "jpeg") { $mime = "image/jpeg"; } if ($extension == "png") { $mime = "image/png"; } if ($extension == "gif") { $mime = "image/gif"; } $image_name=time(). '_'. rand(0,9). rand(0,9). rand(0,9). rand(0,9). '.'.$extension; $target = $_SERVER['DOCUMENT_ROOT'] . "/imageupload/". $image_name; $ok=1; if(move_uploaded_file($_FILES['media']['tmp_name'], $target)) { $last = mysql_query("SELECT uid FROM Images ORDER by uid DESC LIMIT 1",$db); $last = mysql_fetch_row($last); $next = dec2string($last[0] + 1); mysql_query("INSERT into Images (id, name, user, mime) values ('$next', '$image_name', '". $_POST['username']. "', '$mime')",$db); if (isset($_GET['slash'])) { $next .= "/"; } echo "http://myqu.im/g/". $next. ""; echo "
Your file has been uploaded as http://myqu.im/g/". $next; } else { echo "Sorry, there was a problem uploading your file."; } } ?>

< ?php
// Database Login
$db = mysql_connect("localhost", "login", "password");
mysql_select_db("databasename",$db);
< ?php
function string2dec ($string) 
{ 
    global $error; 
    $decimal = 0; 

    $charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; 
    $charset = substr($charset, 0, 62); 

    do {

       $char   = substr($string, 0, 1); 
       $string = substr($string, 1); 

       $pos = strpos($charset, $char); 
       if ($pos === false) { 
          $error[] = "Illegal character ($char) in INPUT string"; 
          return false; 
       } // if 

       $decimal = ($decimal * 36) + $pos; 

    } while($string <> null); 
 
    return $decimal; 
     
} // string2dec 

function dec2string ($decimal) 
{
    global $error; 
    $string = null; 

    $charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; 
    $charset = substr($charset, 0, 62); 

    if (!ereg('(^[0-9]{1,16}$)', trim($decimal))) { 
       $error['dec_input'] = 'Value must be a positive integer'; 
       return false; 
    } // if
    $decimal = (int)$decimal;  

    do {

       $remainder = ($decimal % 36); 

       $char   = substr($charset, $remainder, 1); 
       $string = "$char$string"; 

       $decimal   = ($decimal - $remainder) / 36; 

    } while ($decimal > 0); 

    return $string; 

} // dec2string 

function getExtension($str) {
	$i = strrpos($str,".");
	if (!$i) { return ""; }
	$l = strlen($str) - $i;
	$ext = substr($str,$i+1,$l);
	return $ext;
}
< ?php
include "db.inc.php";
include "functions.inc.php";
foreach ($_GET as $key => $value) { 
	$_GET[$key] = mysql_real_escape_string($value); 
} 
if (isset($_GET['id'])) { 
	$id = $_GET['id'];
	$check = mysql_query("SELECT * FROM Images where id = '".$id."'",$db);
	$check = mysql_fetch_row($check); 
	if ($check) { 
		header("Accept-Ranges: bytes");
		header("Content-Length: ". filesize("imageupload/".$check[3]) );
		header("Content-type:".$check[4]);
		readfile("imageupload/".$check[3]);
		}
	} elseif (isset($_GET['page'])) {
	$id = $_GET['page'];
	$check = mysql_query("SELECT * FROM Images where id = '".$id."'",$db);
	$check = mysql_fetch_row($check); 
	if ($check) { 
		$image = "imageupload/".$check[3];
		$info = getimagesize($image);
		echo '< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


	
	My Quick Image - posted by @'. $check[1]. '
	
	 


';
		echo '
'; echo "\n
"; echo 'Uploaded by '. $check[1]. ''; ?> < ?php echo ' '; } }
# BEGIN WordPress

RewriteEngine On
RewriteBase /
RewriteRule ^g/([a-zA-Z0-9]*)/$ /g.php?page=$1 [L]
RewriteRule ^g/([a-zA-Z0-9]*)$ /g.php?id=$1 [L]
RewriteRule ^u$ /target.php [L]
RewriteRule ^u/$ /target.php?slash=yes [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]


# END WordPress
CREATE TABLE `Images` (
  `uid` int(11) NOT NULL auto_increment,
  `user` text NOT NULL,
  `id` text NOT NULL,
  `name` text NOT NULL,
  `mime` text NOT NULL,
  PRIMARY KEY  (`uid`)
)

Download all files here.

Please note, the code here is not necessarily the final code on the site as I’m one of those constant fiddlers. I’ll try to keep this post up to date with changes, but I may just open the svn repository up publicly if there’s any demand.

Jared Earle is a writer, photographer and systems administrator. You can find him on Twitter most of the time.