One of the most underrated parts of Dabr IMO is the Twitpic upload page. It allows you to interact with a Twitter helper service that uses the same login information as your twitter account. And since Twitter has speced out how the uploadAndPost process works, lots of other Twitter helper services use it in their API – such as YFrog, Twitgoo, Twitvid, and Posterous (which slickly reverse matches your autopost-twitter information in order to validate your posterous account). But Posterous is pretty slick all around – probably the best tumble blog/micro blog/media blog service out there and certainly the most expandable. Perhaps in the future I might try to integrate some more later.
Anyways, I figure I’d give it a go to add some more services to the twitpic page – keyed off a service dropdown. The hardest part in reality was managing the options allowed by each service (i.e. URL upload instead of file upload, additional message body). In addition, I wanted to add support for a site that I use all the time – Imgur. They didn’t implement the uploadAndPost spec so I had to make a few exceptions as well as add an extra step to post the tweet along with the uploaded image file. Took a while to work out all the kinks (one large kink remaining is that Twitvid uploads don’t work LOL) but this page pretty much saves me from ever having to go to those sites again to upload images!
function twitter_twitpic_page($query) { // Check for oAuth credentials if (user_type() == 'oauth') { return theme('page', 'Error', '<p>You can't do media uploads while accessing Dabr using an OAuth login.</p>'); } //verify that we're entering this page from posting the form if ($_POST['service']) { // format and shrink/truncate associated status message $status = prepare_status($_POST['message'],120); // set the api url based on the service name (all similar except imgur) $postUrl = 'http://'.$_POST['service'].'.com/api/uploadAndPost'; // prepare the fields array with the common elements $postData = array( 'username' => user_current_username(), 'password' => $GLOBALS['user']['password'], 'message' => $status,); // perform service-specific tasks switch ($_POST['service']){ case 'imgur': if (!defined('IMGUR_API_KEY')){ twitter_refresh('twitpic/fail/'.$_POST['service'].'/'.urlencode('API KEY undefined')); } // imgur doesn't use the Twitter standard uploadAndPost spec $postUrl = 'http://imgur.com/api/upload.xml'; //if URL is provided, send URL for imgur to rehost, otherwise use selected file if (empty($_POST['url'])){ $postData = array( 'key' => IMGUR_API_KEY, 'image' => '@'.$_FILES['media']['tmp_name']); } else { $postData = array( 'key' => IMGUR_API_KEY, 'image' => $_POST['url']); } break; case 'yfrog': if (!defined('YFROG_API_KEY')){ twitter_refresh('twitpic/fail/'.$_POST['service'].'/'.urlencode('API KEY undefined')); } $postData['key'] = YFROG_API_KEY; // Yfrog can also accept a URL as the media source if (!empty($_POST['url'])){ $postData['url'] = $_POST['url']; } else { $postData['media'] = '@'.$_FILES['media']['tmp_name']; } break; case 'posterous': // Posterous has an additional comments element and will fall through to the default $postData['body'] = stripslashes($_POST['body']); default: $postData['media'] = '@'.$_FILES['media']['tmp_name']; } // make the api call $response = twitter_process($postUrl,$postData); // check response XML for associated IDs // for uploadAndPost supporting services if (preg_match('#mediaid>(.*)</mediaid#', $response, $matches)) { $id = $matches[1]; // Twitvid allows crossposting to Youtube if (preg_match('#youtube_id>(.*)</youtube_id#', $response, $matches)) { $altid = $matches[1]; } // Posterous sends back a separate shortened URL code if (preg_match('#mediaurl>http://post.ly/(.*)</mediaurl#', $response, $matches)) { $altid = $matches[1]; } // show success messsage and pass IDs to create links to media twitter_refresh("twitpic/confirm/".$_POST['service']."/$id/$altid"); } // response for imgur uses different element names elseif (preg_match('#image_hash>(.*)</image_hash#', $response, $matches)) { $id = $matches[1]; // the secret delete link/code is offered only once and should be shown in the confirmation if (preg_match('#delete_hash>(.*)</delete_hash#', $response, $matches)) { $deleteid = $matches[1]; } // we need the actual imgur link in order to post status to Twitter if (preg_match('#original_image>(.*)</original_image#', $response, $matches)) { $imglinkid = $matches[1]; } // update status with the image link $status .= " $imglinkid "; // post the status to twitter $response = twitter_process('http://twitter.com/statuses/update.json', array('source' => 'dabr', 'status' => $status)); // show success message, link to image, and hidden delete link twitter_refresh("twitpic/confirm/".$_POST['service']."/$id/$deleteid"); } else { // collect errors from response if (preg_match('#error_code>(.*)</error_code#', $response, $matches)) { $error = "Error Code: $matches[1]. "; } if (preg_match('#error_msg>(.*)</error_msg#', $response, $matches)) { $error .= "Error Msg: $matches[1]. "; } if (preg_match('#err.code="(.*)" msg="(.*)" />#', $response, $matches)) { $error = "Error Code: $matches[1] Error Msg: $matches[2]"; } // show failure messages twitter_refresh('twitpic/fail/'.$_POST['service'].'/'.urlencode($error)); } } // Page mode to show confirmation and media links elseif ($query[1] == 'confirm') { $postedlink = "Media: http://$query[2].com/$query[3]"; if ($query[2] == 'imgur' && !empty($query[4])){ $postedlink .= " // Hidden delete link: http://imgur.com/delete/$query[4]"; } if ($query[2] == 'twitvid' && !empty($query[4])){ $postedlink .= " // Youtube: http://www.youtube.com/watch?v=$query[4]"; } if ($query[2] == 'posterous' && !empty($query[4])){ $postedlink = "Post: http://post.ly/$query[4]"; } // show formatted confirmation to add thumbnails $content = "<p>Upload success.</p><p>".twitter_parse_tags($postedlink)."</p>"; } // page mode for failure - show errors elseif ($query[1] == 'fail') { $content = "<p>$query[2] upload failed: $query[3]</p>"; } // otherwise show form else { $content = '<style type="text/css">.disabletrue{background:#ddd;}.disablefalse{background:#fff;}</style> <script type="text/javascript">function disable(sel){service=sel.options[sel.selectedIndex].value;sel.form.url.disabled= (service != 'yfrog' && service != 'imgur');sel.form.body.disabled= (service != 'posterous');sel.form.url.className= 'disable'+(service != 'yfrog' && service != 'imgur');sel.form.body.className= 'disable'+(service != 'posterous');}</script> <form name="twitpic" method="post" action="twitpic" enctype="multipart/form-data"><br />Service: <select name="service" onChange="disable(this);"><option value="twitpic">Twitpic</option><option value="twitgoo">Twitgoo</option><option value="yfrog">Yfrog</option><option value="imgur">Imgur</option><option value="twitvid">Twitvid</option><option value="posterous">Posterous</option></select><br />Upload: <input type="file" name="media" /><br />Message: <input type="text" name="message" maxlength="120" /><br />Image Url: <input type="text" name="url" maxlength="120" /><br />Body:<br><textarea style="position:relative;top:-14px;left:67px;" cols=50 rows=3" name="body"></textarea><br /><input type="submit" value="Upload" /></form> <script type="text/javascript">disable(document.forms['twitpic'].service);</script>'; } return theme('page', 'Twitpic Upload', $content); }
I also had to update the twitter_photo_replace function, which I use to show the thumbnail of the image on the confirm page, to add the imgur regexes
'#imgur.com/([w]{5})[s.ls][.w]*#i' => 'http://imgur.com/%ss.png', '#imgur.com/gallery/([w]+)#i' => 'http://imgur.com/%ss.png', '#imgur.com/delete/([w]+)#i' => 'images/trash.gif',
A lot of code, but to me it’s worth it!
Popularity: unranked [?]







































Quoting in Multiply Comment Fields
Ever wanted to quote more than one person in a reply comment field on social networking side Multiply? This bookmarklet might help:
Just drag it to your Links or Bookmarks bar (or right-click it and bookmark/favorite it). It works on Firefox, but I haven’t tried IE or Safari.
What I do is highlight from the end of the response all the way back to the picture of the person on the left (that should select everything including their name), click the shortcut, and it adds the selected text and HTML code to your reply box at the bottom. You can do this as many times as you want – it’ll just keep adding to the reply box.
It’s not smart enough to know if you highlight 2 replies at once (do it one at a time – remember it all adds to the box before you hit “Submit”). Also if you only highlight a part of reply without highlighting who the reply was from, it’ll only quote the text you highlighted. Try it out. Of course, it may stop working if they upgrade the system.
Here are 2 other bookmarklets for:
Check out some other bookmarklets.
Popularity: unranked [?]