Skip to content

Instantly share code, notes, and snippets.

@rjha
Created July 10, 2012 17:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rjha/3084904 to your computer and use it in GitHub Desktop.
Save rjha/3084904 to your computer and use it in GitHub Desktop.
pinterest like image extraction and size determination
webgloo.imagep = new Image();
webgloo.imagep.onload = function() {
if(webgloo.sc.ImageSelector.debug){
console.log(this.src + " : " + this.width + "x" + this.height);
}
if((this.width >= 300) && (this.height >= 300 )) {
webgloo.sc.ImageSelector.addImage(this.src);
}
return false ;
}
webgloo.sc.ImageSelector = {
bucket : {},
images : [],
num_added : 0 ,
num_select : 0 ,
num_upload : 0 ,
debug : false ,
extractEndpoint : "/qa/ajax/extract-image.php",
uploadEndpoint : "/upload/image.php" ,
nextEndpoint : "/qa/external/router.php" ,
imageDiv : '<div id="image-{id}" class="stackImage" >'
+ '<div class="options"> <div class="links"> </div> </div>'
+ '<img src="{srcImage}" class="thumbnail-1" /> </div>' ,
addLink : '<a id="{id}" class="btn btn-mini add-image" href="">Select</a>' ,
removeLink : '<i class="icon-ok"></i>&nbsp;&nbsp;'
+ '<a id="{id}" class="btn btn-mini remove-image" href="">Remove</a>' ,
attachEvents : function() {
$('.stackImage .options').hide();
$('#stack').hide();
$('#next-message').hide();
$("#fetch-link").live("click", function(event){
event.preventDefault();
var link = jQuery.trim($("#link-box").val());
if( link == '' ){
return ;
} else {
webgloo.sc.ImageSelector.fetch(link);
}
}) ;
//capture ENTER on link box
$("#link-box").keydown(function(event) {
//donot submit form
if(event.which == 13) {
event.preventDefault();
var link = jQuery.trim($("#link-box").val());
if( link == '' ) {
return ;
} else{
webgloo.sc.ImageSelector.fetch(link);
}
}
});
$('#next-button').live("click",function() {
//initialize
webgloo.sc.ImageSelector.clearMessage();
webgloo.sc.ImageSelector.num_upload = 0 ;
var counter = 1 ;
if(webgloo.sc.ImageSelector.debug) {
console.log("num_selected :: " + webgloo.sc.ImageSelector.num_select);
}
if(webgloo.sc.ImageSelector.num_select == 0 ) {
webgloo.sc.ImageSelector.showMessage("Please select an image.",{"css":"color-red"});
return false;
} else {
$("#stack .images").find('.stackImage').each(function(index) {
var imageId = $(this).attr("id");
//will split into image and 1
var ids = imageId.split('-');
var realId = ids[1] ;
var imageObj = webgloo.sc.ImageSelector.bucket[realId] ;
if(imageObj.selected) {
webgloo.sc.ImageSelector.upload(counter,imageObj.srcImage);
if(webgloo.sc.ImageSelector.debug) {
console.log("upload image :: " + imageObj.srcImage);
}
counter++ ;
}
});
}
});
$('.stackImage').live("mouseenter",function() {
//will get image-1, image-2 etc.
var imageId = $(this).attr("id");
//will split into image and 1
var ids = imageId.split('-');
var realId = ids[1] ;
imageObj = webgloo.sc.ImageSelector.bucket[realId] ;
if(!imageObj.selected) {
// show select button
var buffer = webgloo.sc.ImageSelector.addLink.supplant({"id": realId } );
$(this).find(".options .links").html(buffer);
}
$(this).find(".options").show();
});
$('.stackImage').live("mouseleave", function() {
//will get image-1, image-2 etc.
var imageId = $(this).attr("id");
//will split into image and 1
var ids = imageId.split('-');
var realId = ids[1] ;
imageObj = webgloo.sc.ImageSelector.bucket[realId] ;
//if this image is selected?
if(!imageObj.selected) {
$(this).find(".options").hide();
}
});
$('.add-image').live("click", function(event) {
event.preventDefault();
var realId = $(this).attr("id");
var imageId = "#image-" + realId ;
imageObj = webgloo.sc.ImageSelector.bucket[realId] ;
//change selected state for imageObj
imageObj.selected = true ;
webgloo.sc.ImageSelector.bucket.realId = imageObj ;
webgloo.sc.ImageSelector.num_select++ ;
// change display
var buffer = webgloo.sc.ImageSelector.removeLink.supplant({"id":realId } );
$(imageId).find(".options .links").html(buffer);
});
$('.remove-image').live("click", function(event) {
event.preventDefault();
var realId = $(this).attr("id");
var imageId = "#image-" + realId ;
imageObj = webgloo.sc.ImageSelector.bucket[realId] ;
//change selected state for imageObj
imageObj.selected = false ;
webgloo.sc.ImageSelector.bucket.realId = imageObj ;
webgloo.sc.ImageSelector.num_select-- ;
$(imageId).find('.options').hide();
});
},
addSpinner : function() {
var buffer = '<img src="/css/images/ajax_loader.gif" alt="loading ..." />' ;
$("#ajax-spinner").html(buffer);
},
removeSpinner: function() {
$("#ajax-spinner").html('');
},
appendMessage : function(message,options) {
options.css = (typeof options.css === "undefined") ? '' : options.css;
$("#ajax-message").append("<div> " + message + "</div>");
if( options.css != '') {
$("#ajax-message").addClass(options.css);
}
},
clearMessage : function() {
$("#ajax-message").html('');
},
showMessage : function(message,options) {
options.css = (typeof options.css === "undefined") ? '' : options.css;
$("#ajax-message").html('');
$("#ajax-message").html("<div> " + message + "</div>");
if( options.css != '') {
$("#ajax-message").addClass(options.css);
}
},
showNextMessage : function() {
if(webgloo.sc.ImageSelector.debug){
console.log("show next message fired");
}
if(webgloo.sc.ImageSelector.num_added > 0 ) {
$("#stack").fadeIn("slow");
$("#next-message").fadeIn("slow");
} else {
var message = "No image of appropriate size found!";
webgloo.sc.ImageSelector.showMessage(message, {"css":"color-red comment-text"});
}
},
addImage : function(image) {
webgloo.sc.ImageSelector.num_added++ ;
var index = webgloo.sc.ImageSelector.num_added ;
if(webgloo.sc.ImageSelector.debug) {
console.log("Adding image : " + index + " : " + image);
}
var buffer = this.imageDiv.supplant({"srcImage":image, "id":index } );
// logo, small icons etc. are first images in a page
// what we are interested in will only come later.
$("div#stack .images").prepend(buffer);
this.bucket[index] = { "id":index, "srcImage": image, "selected" : false} ;
},
processUrlFetch : function(response) {
var images = response.images ;
for(i = 0 ; i < images.length ; i++) {
/*
var img = new Image();
img.onload = function() {
if(webgloo.sc.ImageSelector.debug){
console.log(this.src + " : " + this.width + "x" + this.height);
}
if((this.width >= 300) && (this.height >= 300 )) {
webgloo.sc.ImageSelector.addImage(this.src);
}
}
img.src = images[i] ; */
webgloo.imagep.src = images[i] ;
}
webgloo.sc.ImageSelector.showNextMessage();
},
fetch : function(target) {
//initialize
webgloo.sc.ImageSelector.num_added = 0 ;
webgloo.sc.ImageSelector.num_select = 0 ;
webgloo.sc.ImageSelector.num_upload = 0 ;
webgloo.sc.ImageSelector.bucket = {} ;
webgloo.sc.ImageSelector.images = [] ;
webgloo.sc.ImageSelector.clearMessage();
$("#stack").fadeOut("slow");
$("#stack .images").html('');
endPoint = webgloo.sc.ImageSelector.extractEndpoint ;
params = {} ;
params.target = target ;
//ajax call start
$.ajax({
url: endPoint,
type: "POST",
dataType: "json",
data : params,
timeout: 9000,
processData:true,
beforeSend : function() {
webgloo.sc.ImageSelector.addSpinner();
},
//js errors callback
error: function(XMLHttpRequest, response){
webgloo.sc.ImageSelector.showMessage(response, {"css":"color-red"});
},
// server script errors are also reported inside
// ajax success callback
success: function(response){
if(webgloo.sc.ImageSelector.debug) {
console.log("fetch : server response :: ") ;
console.log(response);
}
switch(response.code) {
case 401 :
webgloo.sc.ImageSelector.showMessage(response.message,{"css":"color-red"});
break ;
case 200 :
webgloo.sc.ImageSelector.processUrlFetch(response);
break ;
default:
webgloo.sc.ImageSelector.showMessage(response.message,{"css":"color-red"});
break ;
}
},
complete :function(response) {
webgloo.sc.ImageSelector.removeSpinner();
}
}); //ajax call end
},
processImageUpload : function(counter,response) {
mediaVO = response.mediaVO ;
webgloo.sc.ImageSelector.images.push(mediaVO);
webgloo.sc.ImageSelector.num_upload++ ;
if(counter == webgloo.sc.ImageSelector.num_select) {
//Actual upload?
if(webgloo.sc.ImageSelector.num_upload > 0 ) {
//stringify images
var strImagesJson = JSON.stringify(webgloo.sc.ImageSelector.images);
//bind to form
frm = document.forms["web-form1"];
frm.images_json.value = strImagesJson ;
$('#web-form1').submit();
}
}
},
upload : function(counter,imageUrl) {
webgloo.sc.ImageSelector.images = new Array();
var message = " uploading image {upload}/{total} ... " ;
message = message.supplant({"upload":counter, "total":webgloo.sc.ImageSelector.num_select});
webgloo.sc.ImageSelector.appendMessage(message,{});
$("#stack .images").html('');
var options = {"css":"color-red"} ;
var prefix = "image " + counter + " : " ;
endPoint = webgloo.sc.ImageSelector.uploadEndpoint ;
params = {} ;
params.qqUrl = imageUrl ;
//ajax call start
$.ajax({
url: endPoint,
type: "POST",
dataType: "json",
data : params,
timeout: 9000,
processData:true,
beforeSend : function() {
webgloo.sc.ImageSelector.addSpinner();
},
//js errors callback
error: function(XMLHttpRequest, response){
webgloo.sc.ImageSelector.appendMessage(response,options);
},
// server script errors are also reported inside
// ajax success callback
success: function(response){
if(webgloo.sc.ImageSelector.debug) {
console.log("upload response for image :: " + imageUrl);
console.log(response);
}
switch(response.code) {
case 401 :
webgloo.sc.ImageSelector.appendMessage(prefix + response.message,options);
break ;
case 200 :
webgloo.sc.ImageSelector.processImageUpload(counter,response);
break ;
default:
webgloo.sc.ImageSelector.appendMessage(prefix + response.message,options);
break ;
}
},
complete :function(response) {
webgloo.sc.ImageSelector.removeSpinner();
}
}); //ajax call end
}
}
$(document).ready(function(){
webgloo.sc.ImageSelector.debug= true ;
webgloo.sc.ImageSelector.attachEvents();
});
namespace com\indigloo\text{
use com\indigloo\Logger;
use com\indigloo\Util;
use com\indigloo\Configuration as Config;
class UrlParser {
/*
* copied from http://www.geekality.net/2011/05/12/php-dealing-with-absolute-and-relative-urls/
* @see also http://publicmind.in/blog/urltoabsolute/
* @rjha changed to modern PHP
*
*/
function createAbsoluteUrl($url, $base) {
//check input
if(empty($url) || empty($base)) { return NULL ; }
// php parse_url will go berserk with space in front
// just try parse_url on " http://www.3mik.com/item/1"
$url = trim($url);
$base = trim($base);
$scheme = \parse_url($url,PHP_URL_SCHEME);
if(!empty($scheme)) {
return $url ;
}
// Urls only containing query or anchor
if(Util::startsWith($url,"#") || Util::startsWith($url,"?")) {
return $base.$url ;
}
// Parse base URL and convert to local variables: $scheme, $host, $path
$pieces = \parse_url($base);
$scheme = (isset($pieces["scheme"])) ? $pieces["scheme"] : "" ;
$host = (isset($pieces["host"])) ? $pieces["host"] : "" ;
// If no path, use /
$path = (isset($pieces["path"])) ? $pieces["path"] : "/" ;
// Remove non-directory element from path
$path = preg_replace('#/[^/]*$#', '', $path);
// Destroy path if relative url points to root
if(Util::startsWith($url,'/')) { $path = ''; }
// Dirty absolute URL
$abs = "$host$path/$url";
// Replace '//' or '/./' or '/foo/../' with '/'
$re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#');
for($n = 1; $n > 0; $abs = preg_replace($re, '/', $abs, -1, $n)) {}
// Absolute URL is ready!
return $scheme.'://'.$abs;
}
function addScheme($url){
$scheme = \parse_url($url,PHP_URL_SCHEME);
if(empty($scheme)) {
$url = "http://".$url ;
}
return $url ;
}
function extractUsingDom($url) {
if(empty($url)) { return ; }
$url = $this->addScheme($url);
$title = "" ;
$description = "" ;
$html = @file_get_contents($url);
$doc = new \DOMDocument();
@$doc->loadHTML($html);
$nodes = $doc->getElementsByTagName("title");
$length = $nodes->length ;
if($length > 0 ){
$title = $nodes->item(0)->nodeValue;
}
$metas = $doc->getElementsByTagName("meta");
$length = $metas->length ;
for ($i = 0; $i < $length; $i++) {
$meta = $metas->item($i);
if($meta->getAttribute("name") == "description") {
$description = $meta->getAttribute("content");
}
}
$nodes = $doc->getElementsByTagName("img");
$length = $nodes->length ;
$count = 0 ;
$images = array();
for($i = 0 ; $i < $length; $i++) {
$node = $nodes->item($i);
$srcImage = $node->getAttribute("src");
$absUrl = $this->createAbsoluteUrl($srcImage,$url);
if(!empty($absUrl)) {
// @todo get rid of question mark at the end of img src?
// this will interfere with images generated from scripts
array_push($images,$absUrl);
$count++ ;
}
if($count > 19) break ;
}
$response = new \stdClass;
$response->title = $title ;
$response->description = $description ;
$response->images = $images ;
return $response ;
}
<div class="row">
<div class="span12">
<h2> upload images from a webpage </h2>
<div class="hr"> </div>
<?php FormMessage::render(); ?>
<div class="row">
<div class="span7">
<table class="form-table">
<tr>
<td>
<label>Type webpage URL and click fetch ( or press Enter ) </label>
<input id="link-box" name="link" value="" />
<button id="fetch-link" type="button" class="btn" value="Fetch">Fetch</button>
</td>
</tr>
</table>
<div id="ajax-spinner" class="ml20 p10"> </div>
<div id="ajax-message" class="ml20 p10"> </div>
</div> <!-- 1:span7 -->
<div class="span5">
<div id="next-message" class="p20">
<p> Place your mouse over an image to select it. Please click Next button after selecting images. </p>
<form id="web-form1" name="web-form1" action="/qa/external/router.php" method="POST">
<button id="next-button" class="btn btn-inverse" type="button" name="next" value="Next" onclick="this.setAttribute('value','Next');" ><span>Next&nbsp;&rarr;</span></button>
<input type="hidden" name="images_json" />
<input type="hidden" name="qUrl" value="<?php echo $qUrl; ?>" />
<input type="hidden" name="fUrl" value="<?php echo $fUrl; ?>" />
</form>
</div>
</div> <!-- 1:span5 -->
</div> <!-- row:1 -->
<div class="row">
<div class="hr"> </div>
<div id="stack">
<div class="images p10"> </div>
</div> <!-- stack -->
</div> <!-- row:2 -->
</div> <!-- span12 -->
</div> <!-- row -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment