I enjoy things that are random. I think the two things I try to do the most in my code is automation and random. so it makes sense to do a fun automation/random script. Like this one.

I was working on a Perl project (*coming soon* - if it works as well as I think it will, then it should be pretty popular) and mentioned it to a friend. We were also discussing funny eBay feedback (if you haven't see either this or this, they are both great). That eventually led to an idea that it would be funny if a script grabbed a random porn image and a random feedback phrase from eBay and then combined them. "Great Package! AA+++" has pretty obvious connotations on porn.

I am moving soon and have given notice where I work, so my workload has been light this week... as a result, I went ahead and wrote this.
I didn't feel it was appropriate to test it out on porn sites while at work, so I chose a different avenue.

This script has an array of names. It randomly chooses a name from that array, and then randomly chooses a number between 0 and 500. Then it appends that to the name and looks it up on eBay. If it is a user and has feedback, it grabs 10 of their most recent comments and chooses a random one.

The script then goes to Yahoo's news page where they list the most popular images for the last 5 mins, and it grabs an image off of that page.

Then it slaps that phrase onto the image and displays it.

Outside of the script I have added some functionality to allow people to vote up or down (obviously slightly similar to the way perlmonks itself does it). Then I have a script that looks to see how many total votes an image has - if it is over a certain threshold of total votes and has enough negative votes, it gets deleted.
that way all of my diskspace isn't taken up by these things, but it does allow the good/funny/scary ones to stick around.

I am still adding in more functionality over the next few days - but the Perl code will stay the same (functionality wise - in terms of being sped up, I'd imagine there is a lot more that could be done).
If the image is a jpeg, then it is smaller and looks a lot better than the other formats I tried.
If the text doesn't have a light background, then it is hard to read. I thought about doing image analysis on the pixel level and see if the area where the text will go is a certain color, place text of an opposite color there so that it will show up.
But in the end, while less pretty, it was much easier to just have it show a white box since that is built in.

If you want to check out the code in action (I must reinforce the concept that I didn't write any of these - they are all random - some of them are really offensive - war pics and stuff), go here.

In the directory of all images, there is a history of changes, so there are some with diff color text, no text, badly placed text, etc.

Here is the code, with comments (feel free to suggest areas where I was retarded and changes could make it faster):
#!/usr/bin/perl -w #I wrote this. Therefore I'm special. Like the Special Olympics. #Eric Smith (stenz@cardboardutopia.com) #this script looks up eBay feedback given by a user #it then gets an image from Google's images #it then superimposes the eBay feedback over the image. #hilarity ensues. #this is the url to use to look up user feedback. the number at the en +d can be varied to allow more hits #but smaller is faster #http://cgi2.ebay.com/aw-cgi/eBayISAPI.dll?ViewFeedbackMemberLeft&memb +erId=andy46477&items=100 #http://cgi2.ebay.com/aw-cgi/eBayISAPI.dll?ViewFeedbackMemberLeft&memb +erId=stevebo&items=100 #funny users: andy46477 and stevebo #swap out their names with whatever you like, or random use LWP::Simple;#so we can reach out and fondle something use Image::Magick; #use GD;#this has easy text too I think, but I don't have the jpeg abi +lity on my pair.com server #add whatever names you fancy my @names = qw(andy sue joe john fred bob larry hector nate albert lis +a sam ken tim tasha tom katie george will jim susan sam hugh bill kristen); #or just put something in the $fixedUser var my $fixedUser = ""; #time to iterate my $stopMe = 0; my $randNum = 0; my $currUser = ""; my $page = ""; while($stopMe==0){ if(length($fixedUser) > 0){ #there is a user to use - so use them $currUser = $fixedUser; } else{ #create a random number $randNum = int(rand 500) + 1; #otherwise, pick a random name, and append on our random numbe +r $currUser = @names[int(rand (scalar(@names)))] . $randNum; } #get the ebay page $page = get("http://cgi2.ebay.com/aw-cgi/eBayISAPI.dll?ViewFeedbac +kMemberLeft&memberId=$currUser&items=10"); #check to see if it has "not a registered eBay user" in it - if so +, try a new name combo and hit it again if($page =~ /not a registered eBay user/ || $page =~ /No Feedback +has been left by/ ){ #try again } else{ $stopMe = 1;#we now have data } } #now search for "</strong>" and then grab everything until the next "< +/td>" and dump results into an array my @feedback = (); my $phraseStart = '</strong>'; my $phraseStop = '</td>'; my $pos1 = 0; my $pos2 = 0; my $tempFeedback = ""; $stopMe = 0; while($stopMe==0){ $pos1 = index($page,$phraseStart,$pos1);#get the position of the f +irst place $phraseStart shows up if($pos1 != -1){ $pos1 = $pos1 + length($phraseStart);#add on the length of + $phraseStart so that we are starting on the other side of that $pos2 = index($page,$phraseStop,$pos1);#get where to s +top for this phrase $tempFeedback = substr($page,$pos1,($pos2-$pos1)); +#praise be with you push(@feedback, $tempFeedback);#add that onto +the array of feedback $tempFeedback = "";#reset that #move the start pos up to the end of where we last looked $pos1 = $pos2 + length($phraseStop); } else{ #it couldn't find anything, so we are out of $stopMe = 1; } } #now we have all the feedback - pick a random one from there and that +will be our phrase my $randomFeedback = $feedback[int(rand (scalar(@feedback)))];#occasio +nally in other languages. hilarity ensues. unless they are French. #the string "&#38;" and others like that shows up a lot in these - som +e sort of html formatting #strip that out $randomFeedback =~ s/&#..;//; #now we will use the yahoo page for the most popular photos over the p +ast 5 mins my $yahooPage = get('http://news.yahoo.com/news?tmpl=index2&cid=995'); #now we scan over that and get the images from there into an array #look for img tags, see that they end in jpg, and then get their url #then there are two methods that have to be attempted based on the cas +e #1) if the url has "/t" in it, then that has to be swapped out with "/ +i/" #or #2) if the url has "thumb." in it, that needs to be swapped out with " +.capt" # #if it doesn't have either of those, then just skip over it and look a +t the next thing. #reset and reuse these $pos1 = 0; $pos2 = 0; $stopMe = 0; my $initPhrase = 'class=article'; my $imgStart = 'src="'; my $imgStop = '"'; my $check1 = '/t/'; my $check2 = 'thumb.'; my $replace1 = '/i/'; my $replace2 = 'capt.'; my @imageArray = (); my $tmpImgURL = ""; #first we find where "class=article" shows up - that will be very clos +e to the images - any higher in the page and #we are more likely to get ads and navigation images $pos1 = index($yahooPage,$initPhrase,$pos1); $pos1 = $pos1 + length($initPhrase); #now while loop over it all, gettin all grabby and stuff while($stopMe==0){ #next we look for 'src=' and grab everything up until the closing +quote $pos1 = index($yahooPage,$imgStart,$pos1);#get the position of the + first place $imgStart shows up if($pos1 != -1){ $pos1 = $pos1 + length($imgStart);#add on the length of $i +mgStart so that we are starting on the other side of that $pos2 = index($yahooPage,$imgStop,$pos1);#get where to + stop for this img $tmpImgURL = substr($yahooPage,$pos1,($pos2-$pos1) +);#praise be with you #check to see if it contains either $check1, or $check2 #also make sure that is a ".jpg" if($tmpImgURL =~ /\/t\// && $tmpImgURL =~ /.jp +g/){ #swap out text to get right url $tmpImgURL =~ s/$check1/$replace1/gi; push(@imageArray, $tmpImgURL);#add that on +to the array of imgaes } elsif($tmpImgURL =~ /thumb./ && $tmpImgURL =~ /.jpg/){ #^not sure if it is looking on that period up there - it w +orks though #swap out text to get right url $tmpImgURL =~ s/$check2/$replace2/gi; push(@imageArray, $tmpImgURL);#add that onto the array + of imgaes } $tmpImgURL = "";#reset that #move the start pos up to the end of where we last looked $pos1 = $pos2 + length($imgStop); } else{ #it couldn't find anything, so we are out of $stopMe = 1; } } #now we have an array of potential images - randomly pick one my $imgChoice = $imageArray[int(rand (scalar(@imageArray)))]; #now we have our random image, and our random text. #create a unique filename my $fileName = "$^T$$" . $currUser . '.jpg';#jpg allows better pics an +d the font shows up good enough my $tmpDir = 'someTmpDirName/'; #grab our random image and save it to disk getstore($imgChoice,"$tmpDir$fileName"); #now use Image::Magick and write our text onto the image #annoying parts: 1) to make sure the text doesn't run off the edge, 2) + to make sure that it is visible over the colors #2 is taken care of by adding a backcolor in Annotate call - sometimes + still spills out my $image = new Image::Magick; $image->Read("$tmpDir$fileName"); my ($width, $height) = $image->Get('width','height'); #now looking at the width, and assuming that we will leave 5 pixel buf +fer on either edge, #calculate where line breaks in text need to go for word wrapping - I +don't see a built-in way to do this #each letter at this size looks like it takes up about 7 pixels my $displayWidth = $width; $width = $width - 40;#to account for sides my $difference = 20; #if the string is less than the size of the pic, leave it alone #otherwise, see if it needs 2 or 3 lines if(length($randomFeedback)*7 > $width){ #thanks to japhy from perlmonks for this bit my $half = int(length($randomFeedback)/2); $randomFeedback =~ s {( ?)([^ ]*)(?<=^.{$half})([^ ]*)( ?)} { length($2) < length($3) ? "\n$2$3$4" : "$1$2$3\n" }e; $difference = 30; } #this seems to disregard the antialias call $image->Annotate(pointsize=>14,x=>20,y=>$height-$difference, antialias +=>true, fill=>'black', text=>$randomFeedback, undercolor=>'white'); $image->Write("$tmpDir$fileName"); #I should also probably note that if that bizzitch can't swim, then sh +e's bound to drizzown. #display out to screen - actual stuff is not important for demo here


-------------------------------------------------------------------
There are some odd things afoot now, in the Villa Straylight.

Replies are listed 'Best First'.
Re: Random images + random text == funny
by Aristotle (Chancellor) on May 03, 2003 at 02:48 UTC
    This is kind of fun, although using eBay feedback for the text makes for usually very sameish captions. It might have worked for porn.. For news images, I'd find a different source for the captions.

    Makeshifts last the longest.

      Yeah, I very much agree. Most of them are boring, and very few are funny - more just irony or interesting juxtaposition. But every now and then there are some real great ones that make it fun. I want to improve the voting/cleanup system so that it gets rid of some of the junk.

      I'm also going to go in today and set it up include a larger image pool, and the text pool as well - will yank from varied sources.

      I don't get a ton of hit right now. But as the system is now, for every hit that I get on that page, the servers from which I grab content also take that hit. So I think I will add in scripts that run every hour and hit sites, pulling down a pool of content, and then my code will just poll that local content. That way any outside sites would only get hit once an hour by me, instead of taking a hit everytime.

      Still not a perfect solution, but nicer (more polite) than what it does now.

      -------------------------------------------------------------------
      There are some odd things afoot now, in the Villa Straylight.