Posts Tagged 'Javascript'
2011-03-26

I was recently playing around with node a command line javascript interpreter based on the V8 javascript engine and wanted/needed to implement a file downloader class that properly handles HTTP 302 Redirects.

After a bit of yelling and screaming, I had a working implementation
Enter the Javascript

var path require('path');
var url require('url');
var http require('http');
var fs require('fs');
var write_file;
//what global variable do we have?
var complete false;
var content_length 0;
var downloaded_bytes 0;

//create the downloader 'class'
var Downloader function() {

  //we will need to be able to set the remote file to download
  this.set_remote_file function(file) {
    remote_file file;
    local_file path.basenameremote_file );
  }
  
  //we want to set the local file to write to
  this.set_local_file function(file) {
    local_file file;
  }
//run this fukker!
  this.run function() {
    //start the download
    this.downloadremote_filelocal_file);
  }

  this.download function(remotelocalnum) {
    console.logremote );
    if num 10 ) {
      console.log'Too many redirects' );
    }
    //remember who we are
    var self this;
    //set some default values  
    var redirect false;
    var new_remote null;
    var write_to_file false;
    var write_file_ready false;
    //parse the url of the remote file
    var url.parse(remote);
    //set the options for the 'get' from the remote file
    var opts = {
      hostu.hostname,
      portu.port,
      pathu.pathname
    };
    //get the file
    var request http.get(optsfunction(response ) {
      switch(response.statusCode) {
        case 200:
          //this is good
          //what is the content length?
          content_length response.headers['content-length'];
          break;
        case 302:
          new_remote response.headers.location;
          self.download(new_remotelocal_filenum+);
          return;
          break;
        case 404:
          console.log("File Not Found");
        default:
          //what the hell is default in this situation? 404?
          request.abort();
          return;
      }
      response.on('data'function(chunk) {
        //are we supposed to be writing to file?
        if(!write_file_ready) {
          //set up the write file
          write_file fs.createWriteStream(local_file);
          write_file_ready true;
        }
        write_file.write(chunk);
        downloaded_bytes+=chunk.length;
        percent parseInt( (downloaded_bytes/content_length)*100 );
        console.log( percent );
      });
      response.on('end'function() {
        complete true;
        write_file.end();
      });
    });
    request.on('error'function(e) {
      console.log("Got error: " e.message);
    });
  }
}
exports.Downloader Downloader;

To use this, one would need to create a script that utilizes the class. For example, suppose we wanted to download an episode of Rathole Radio we would need to write something along the lines of the following:

var Downloader = require('./Downloader');
var dl = new Downloader.Downloader();
dl.set_remote_file('http://traffic.libsyn.com/ratholeradio/RR048_20_03_11.ogg');
dl.run();

Awesome 'Possum! Now quit reading and go do something nifty.

Comments
2011-03-27 jrobb:
nifty indeed!
2012-01-08 BenNG:
Thanks for the article :)
I was wondering something : the variable local in " this.download = function(remote, local, num) {...}" is never used right ?
2012-01-08 jezra:
@BenNG, haha! it certainly appears that way. The lines that actually write to the local file should probably be changed to use 'local' instead of 'local_file', or 'local' should be removed from the method.

It really comes down to scope preference.
Name:
not required
Email:
not required (will not be displayed)
Website:
not required (will link your name to your site)
Comment:
required
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
Problem:
5 minus 5
Answer:
required
2010-04-17

Recently, it became necessary for me to add a "share on facebook" feature to a project I am working on. A quick web search for "facebook share api" turned up the Facebook Share API that gives example code for for formatting a URL to share data on Facebook.

The ony problem the Facebook share code is that the code doesn't work. A custom title for what is being shared get's overridden by the title of the page at the given URL. A bit more digging with my internet shovel turned up some information about URL and Title being sent as part of an array and the URL would be sent as p[url] and the Title would be sent as p[title].

With that in mind, I wrote the following JavaScript function to format a URL and Title and share them on Facebook.

function shareOnFacebook(share_title,share_url) {
    //encode the share_title
    t=encodeURIComponent(share_title);
    //encode the share_url
    u=encodeURIComponent(share_url);
    //determine the target url to open
    target_url='http://www.facebook.com/sharer.php?s=100&p[title]='+t+'&p[url]='+u+'&t='+t;
    //open the target
    window.open(target_url,'share','toolbar=0,status=0,width=600,height=400');
}

Now quit reading, and go share some useless information of Facebook.

By the way, there is a 100 character limit for the title.

Update June 18 2010: Since both images and description have been asked for... The following function will allow the user to also set the image and description (which facebook call subject for some asinine reason)

function shareOnFacebook(title,url,desc,image) {
    t=encodeURIComponent(title);
    d=encodeURIComponent(desc);
    u=encodeURIComponent(url);
    i=encodeURIComponent(image);
    share_url='http://www.facebook.com/sharer.php';
    share_url+='?s=100&p[title]='+t+'&p[summary]='+d+'&p[url]='+u;
    share_url+='&p[images][0]='+i;
    share_url+='&t='+t+'&e='+d;
    var myWindow = window.open(share_url, 'sharer', 'toolbar=0,status=0,width=626,height=436');
}

Well there you have it, I hope it works for you.

PS. If you are so inclined, you could buy me a cup of coffee. hint hint wink wink

Comments
2010-05-06 neuholger:
Great, this script is working on my page. But how can I add an Image?

All the tests for the meta Tags didn't work including the
<link rel="image_src" ...
2010-05-06 neuholger:
Yeah, I found a solution!
With that solution, you can also integrate several thumbnails.

// Javascript for ShareOnFacebook Buttons
function shareOnFacebook(share_title,share_url,icon_url) {
//encode the share_title
t=encodeURIComponent(share_title);
//encode the share_url
u=encodeURIComponent(share_url);
//encode the icon_url
i=encodeURIComponent(icon_url);
//determine the target url to open
target_url='http://www.facebook.com/sharer.php?s=100&p[title]='+t+'&p[url]='+u+'&t='+t+'&p[images][0]='+i;
//open the target
window.open(target_url,'share','toolbar=0,status=0,width=600,height=400');
}
2010-05-06 jezra:
Yea! that's the spirit.
Thanks for posting the solution to use images. It is the visual aspect of sharing that really packs a punch
2010-06-17 Anonymous:
Any idea how to add a more elaborate description ? except from the title ?
2011-03-22 Rich Jaffke:
I was going to contribute but when I clicked the "cup of coffee" link the page has no way to contribute.
Name:
not required
Email:
not required (will not be displayed)
Website:
not required (will link your name to your site)
Comment:
required
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
Problem:
2 plus 4
Answer:
required
2010-02-03
Although I had thought about updating the look of my music page for a while, other things took precedent. Well, as life sometimes is, I was introduced to a feature in one of the finer browsers that one can use.

The Feature
Picture if you will.......
friend: you should fix your music page cuz it's crap
me: what?
friend: I went there and didn't know what to do
me: did you click the arrow pointing to the right that typically signifies "play"?
friend: what arrow?
me: whoa! what browser are you using?
friend: firefox
me:(pretending to be Morpheus) Show Me!

On my music page, I had a bunch of <audio> tags so that visitors to my site could hear me butcher various tunes that I have recorded. Unfortunately, the Firefox theme that my friend was using made Firefox's default audio player completely unusable.

Fine, I didn't like the look of the default player anyway!

What I Should Have Done
In hindsight, I should has just written some hardcoded javascript and CSS to make a nifty HTML5 audio player thing because I have decided that I really don't like working with JavaScript. Using a framework like GWT or Pyjamas that outputs JavaScript is fine, but hacking on JavaScript just isn't my thing. I suppose that it might have been easier if I had used a large JavaScript library like JQuery, but where is the hell is the fun in that? Oh well, maybe next time.

What I Did Do
Since my music page is created dynamically from information pulled from a database, I wanted a way to dynamically generate an HTML5 audio player based upon formatted text on a page; and well... that's what I did, and I named the project PagePlayer (boring, I know). By building it myself, I know exactly how the controls will look in various browsers, regardless of which theme the browser is using.

It may not be the best looking JavaScript generated music player thingy on the web, but it is my JavaScript generated music player thingy.

So fire up your HTML5 compatible browser and head over to my "music" page to check it out. Anyone interested in the code should visit the PagePlayer project page, where the HTML,JavaScript,CSS, images, and audio can be downloaded.

Now stop reading, and check your code for graceful degredation and IE6 compatibility.
Comments
Name:
not required
Email:
not required (will not be displayed)
Website:
not required (will link your name to your site)
Comment:
required
Please do not post HTML code or bbcode unless you want it to show up as code in your post. (or if you are a blog spammer, in which case, you probably aren't reading this anyway).
Prove you are human by solving a math problem! I'm sorry, but due to an increase of blog spam, I've had to implement a CAPTCHA.
Problem:
6 minus 6
Answer:
required
subscribe
 
2014
2013
2012
2011
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008