bittorrent

Birdtorrent Demo Day

Today I had the privilege to demo Birdtorrent 1.0.0pre to my professor, Dave Humphrey. He appeared to be quite impressed with the work I had done and my future commitment to the project considering the huge difficulty I was faced with throughout the last eight months. As far as the content of the demo, the last blog post covers much of what was seen. To recap, I have a more intuitive UI hooked up and auto-import works via watch folders. In other words, all the functionality is in place that I envisioned for Birdtorrent 1.0. The remainder of this post will go into details about the code changes:

XUL

<popupset>
  <tooltip id="moretip" orient="vertical" style="background-color: #FFFFCC;">
    <description id="descProgress" value="Initializing..."/>
  </tooltip>
</popupset>

<groupbox flex="1">    
   <label id="torrent-download-output" value="Initializing torrent download..." />
   <hbox align="center">
      <image id="imgDownloadComplete" src="" />
      <label id="lblDownloadComplete" value="Complete!" style="visibility: hidden" />
      <progressmeter id="torrent-download-progress" mode="undetermined" tooltip="moretip" 
           style="margin-left:-55px;"/>
      <label id="lblDownloadRate" value="" />
   </hbox>
   <hbox align="center">
      <label id="lblEstimateTime" value="" />
   </hbox>
</groupbox>

The above code uses some rather basic XUL elements. This includes a tooltip, label, image, and progress meter. The most complex element used here is the progress meter. "undetermined" means that the animated candy-cane bar is displayed. I just change this to "determined", using Javascript, once some download information exists.

JS
There really isn't anything dramatic in Javascript that was performed. It is really just a bunch of document.getElementById("id").setAttribute("attrib", "value"); calls. Here is the code for updating the progress bar:

   var progressNode = doc.getElementById("torrent-download-progress");
   if (progressNode != null) {
      progressNode.setAttribute("mode", "determined");
      progressNode.setAttribute("value", percent);
   }

C++
As far as the UI is concerned, all I changed here was the string generation. I thought for a while about how to best format the string for parsing. I initially wanted to come up with some character that was so obscure that I could rest my fears of that being used as a character in the information I was pulling from the torrent. After much thought on the issue, I decided to use strings of characters instead of a single character. While it is completely possible for these strings to preexist in the torrent information, the likelihood of that happening is far less than that of a single character. Basically, this meant the string went from this:

"name - sizeComplete / sizeTotal MB downloaded - Rate: rate KB/s - Peers: peers (percent%)"

to this:

"BEGIN->NAME:name|SIZECOMPLETE:sizeComplete|SIZETOTAL:sizeTotal|RATE:rate|PEERS:peers|PERCENT:percent<-END"

This may seem much more confusing in reading, but it makes a lot more sense in code.

Watch Folders Implementation
Some of you may remember that I was able to implement auto-import by remapping the torrent download directory to a watch folder. This is less than ideal, but it works. For the purposes of the open source course for which I am doing this project, it made the most sense. If you want to get more detail about how this works and the code behind it, feel free to read this blog post.

Anyway, that about covers the entire demonstration. I look forward to releasing Birdtorrent 1.0 soon and presenting it to my academic peers.

Cheers!

P.S.

Based on the recommendations of an anonymous commenter who called out my laziness with Estimated Time (i.e. displaying hour(s) instead of dynamically displaying "hours" or "hour"), I have put some logic in place to improve this information. Estimated Time now displays hour/minute/second for one and hours/minutes/seconds for any number greater than one. It is also smart enough to recognize 0 time. For example, 4:00:23 displays as "4 hours 23 seconds". Finally, instead of displaying "Infinity" when the torrent initially starts downloading (0 divided by anything is infinite), it displays "unknown". I think the anonymous commenter will agree that this is a much better way of handling things.