Transmission on the iPad


Transmission is the default torrent client for most Linux distros. It has fast download speed and requires minimal system resources. Now the iPad 2 has been jailbroken, you can download torrent directly to your iPad by installing Transmission in Cydia. However, as the following screenshot shows, this app doesn’t have an app icon once it is installed.

20120124-164147.jpg

In order to access the app, just open Safari on the iPad and type localhost:9091.

20120124-164604.jpg

But there is one issue. Because this app is a daemon, it’s same as a service in Mac/Windows, meaning that the app won’t run until the next time iPad is started, you need to restart your iPad by pressing the sleep button, swipe to power off the device, wait a moment, and press the sleep button again to start the device.

Once the iPad is restarted, open Safari and go to localhost:9091. Then you can start to download torrent by tapping the Open button and paste in the torrent URL.

If you don’t think you can remember this URL or don’t want to type this URL every time you want to download or check the torrent, you can bookmark this URL.

20120124-170446.jpg

Or if you want more quick way to access the app, the ideal solution is to place an icon on the SpringBoard (or Home Screen) by tapping the ‘Add to Home Screen’ button.

20120124-171013.jpg

This way you can access the app directly on the Springboard with an added bonus of removing the address bar.

20120124-171229.jpg

One more thing to remember is that you can view the torrent details (including where the files are downloaded to) by tapping the Inspector button.

20120124-173354.jpg

After the download is completed, you can either use an iPad app to view the files or transfer to Mac/PC depending on their usages.

iPad 2 Jailbroken!


As you can see in the heading above, I changed the blog name as well as its description to cover more development topics. In addition to web development, I will also discuss mobile development, mainly iOS and Android since I owned iPad 2 and Nexus One.

With the recent jailbreak for A5 devices (iPad 2 and iPhone 4S) released, my iPad 2 has been very useful to me like never before. I installed some Cydia apps such as VLC Media Player, iFile, and Transmission as well as some other Cydia apps and tweaks

Installed Jailbreak apps on my iPad

Installed Jailbreak apps on my iPad

Installed jailbreak tweaks (extensions) on my iPad

Installed jailbreak tweaks (extensions) on my iPad

Now that the jailbreak for my iPad is completed, I will be focused on developing Cydia apps. I will post some tutorials on how to develop for Cydia as I learn from across the web, as well as any tips I found when I’m using my iPad.

Apology to my Twitter and identi.ca Followers


This is a quick post to apology all of my Twitter and identi.ca followers for receiving unwanted spam updates from my account.

Because I didn’t login to my social accounts for a long time, I’m surprised to see that there are lots of spam updates in both accounts. All of these updates came from my long-forgotten Tumblr account. It clearly shows that someone has hacked to my Tumblr account.

I disconnected Twitter from the Tumblr account as well as deleted my ping.fm account for posting to identi.ca. For the security measure, I also changed my Tumblr password and closed this account for good.

From this accident I learned that never link the social network accounts to any third-party apps, because you never know when these third-party accounts gets hacked and ruin your social network accounts updates.

A few Updates and some Information regarding SOPA / PIPA


I had not posted anything for a while. So in this post, I will talk about the upcoming updates for this blog as well as this website as whole and my opinion for the SOPA/PIPA bills.

During the last few weeks, I have learned the ins and outs of WordPress, including WordPress multi-site feature, themes, plugins, etc.

In the coming weeks, I will install WordPress to my main site, robbychen.com, create a portfolio theme or a child theme out of an existing portfolio theme out there, and make my main site as my portfolio to showcase the web development and video projects I finished in the past.

I’m also probably to remove this blog as well as MySQL database that associated with it to migrate it to the main site using the multi-site feature.

That’s all for the update. Now for my opinion about the SOPA / PIPA bills.

In the last couple of days, I read so much about these two bills and how bad they are. I even joined the blackout protest yesterday on this domain. I always thought that the Internet piracy is illegal until I stumbled across this TED presentation.

It basically stated in the presentation that the large media companies have been behind these copyright bills since decades ago. They don’t want us to become the producers and share contents around. They want us to become consumers and just be the “couch-potatoes”. I think that’s why the Internet piracy is born to encourage people to share contents with each other.

Therefore, even if these two bills passed into laws, there will still be a large army of pirates to challenge these companies and find another way to share contents.

Working with jQuery and CakePHP


Recently I’m working with CakePHP and SQLite to develop a gallery for a client. This is going to be my first CakePHP app.

While I’m working on the admin section, I wanted to allow the client to see the image once the image filename field is out of focused so that he could see if it’s the correct image.

The only JS library included with CakePHP is Prototype. Fortunately, the latest version of CakePHP (1.3.11 as of right now) allows us to include with other JS library. I included jQuery with the help of Js helper:

var $helpers = array("Js"=>array("Jquery"));

The above code is included with the whatever controller(s) you want to use this helper. In my case is galleries_controller.php and images_controller.php.

Then I just need to add the following code into the corresponding views, in my case is some of the admin views (admin_edit.ctp, and admin_add.ctp):

echo $this->Js->set("imageLoc", $this->Html->image("0"));

echo $this->Js->get("#GalleryCover")->event("blur", "$('#cover').html(window.beta.imageLoc.substring(0, window.beta.imageLoc.length-12) + 'images/' + $('#GalleryPath').val() + '/thumb/' + $(this).val() + '\" />');");

Note that I used image object in the Html helper to generate a dummy img tag so that I could precisely get the image folder location in the webroot folder. Then I used set object in the Js helper to transfer this generated PHP value to Javascript variable “imageLoc”. The second line is self-explanatory if you know jQuery. Here is the documentation in the CakePHP Cookbook for you to review.

In the jQuery code section of the second line, I used the substring function to remove the last 12 characters in the img tag (0″ alt=”" />). And used the html function to include the generated code into the “cover” div. Every time the “GalleryCover” field is blurred out of focus, the image inside the “cover” div would change to the corresponding images.

If you need more information on how to use CakePHP generated Javascript variables, please refer to the second article in the reference section.

Do you have any other tips on how to incorporate jQuery into CakePHP? Please share them in the comment below.

Reference

Switching to Mac


Switching from Ubuntu to Mac
After several months of deciding which OS I’m going to switch next because I don’t like how Ubuntu is going since 10.10, I have been giving Mac OS X a try.
Macbook Air 13-inch
I bought an old 13 inch Macbook Air first generation from eBay one months ago and have kept using it since then. When I used this Macbook Air which is from 2008 for the first time, I immediately felt love for it.

Perhaps because there are some similarities between Mac OS and Linux commands, working in the Terminal app is like a second nature to me. Plus, with my experience with Windows in the past, I already knew most of the common operations on the Mac.

The main reason I like to try Mac is because of the influence of my iPod Touch. Yes, I’ve still kept my old second generation iPod Touch along with my Nexus One, with the latest iOS installed. After I switched to Android (Nexus One) for a long time and restart using iPod Touch to perform the iOS-specific tasks, I feel that the Android interface is kind of old compare to the iOS’s.

Mac OS X Lion

Several weeks after the purchase of Macbook Air, I upgraded to the latest version of Mac OS X, Lion (10.7). I love this upgrade, especially the Full Screen and Mission Control features.

As a developer and programmer, I like trying new programming languages such as Objective C and AppleScript. Oh, except Java, because I think Java is too complicated for me to understand, that’s why I avoid programming for Android. With the Macbook Air, I could use Xcode to learn and experiment with these programming languages in no time.

For future posts, I will explore some of these programming languages. This blog will have the same topic (web-related programming) plus new programming languages. I will redesign the blog corresponding to my Mac usage in the near future as well.

Of course, I will continue to use Ubuntu 10.04 as my laptop is still running it. Right now and for the time being however, I’m using Mac more than Ubuntu because I just can’t resist the Mac OS’s interface :) Not only its interface, I also enjoy using its hardware. I especially chose to buy Macbook Air over other Macbook laptops because of its lightness and fast processing power.

Look forward to my future posts which will be written in the new OS environment.

Do you have any experience on how to use Mac OS X and Ubuntu/Linux together without sacrifice Ubuntu/Linux? Discuss your experience below.

Writing Generic (Reusable) Code


In C programming language, void pointers and function pointers are used to write generic, reusable code.

These two types of pointers in combination allow to design and implement an algorithm that is independent of the data being manipulated.

For more information about this generic code concept, read the Notes on Programming in C by Rob Pike.

Function Pointers Usage


The statement below is from the last post:

void (*func_ptr)(emp *e);

The above variable can be assigned as follows:

func_ptr = read_emp; // Note that no & is required before read_emp

The following two statements are different from each other:

func_ptr = read_emp; // assign the function address of read_emp to a function to pointer variable func_ptr
func_ptr = read_emp();	// runs the function named read_emp() and saves function results to the variable func_ptr

Here is the sample code for the function pointers:

/*
 *
 * funcptrs.c
 *
 * Program to demonstrate the use of function pointers
 *
 * by Mark Virtue, 2001.
 *
 */

#include <stdio.h>
#include <stdlib.h>

static void goodbye() {
	while (getchar() != '\n') {}
	printf("\nPress ENTER to exit: ");
	fflush(stdin);
	getchar();
}

static int add(int a, int b) {
	return a + b;
}

static int subtract(int a, int b) {
	return a - b;
}

main() {
	int x, y;
	int result;
	int (*func_ptr)(int, int);

	atexit(goodbye);

	printf("Please enter the first number: ");
	scanf("%d", &x);
	printf("Please enter the second number: ");
	scanf("%d", &y);

	while (getchar() != '\n') {}

	printf("Would you like to add or subtract (a/s)? ");
	fflush(stdin);

	if (getchar() == 'a') {
		func_ptr = add;
	}
	else {
		func_ptr = subtract;
	}

	result = func_ptr(x, y);

	printf("The result is %d\n", result);

	return 0;
}

Note in the above code, the add and subtract functions need to have the same structure in order for use with the function pointer.

Here is another sample code which uses a function in the standard C library called qsort():

/*
 * qsort.c
 *
 * Program to demonstrate the use of function pointers
 * This program uses the library function qsort():
 *
 * void qsort(void *array, int count, int size, int (*comp_func)(const void *, const void *))
 *
 * by Mark Virtue, 2001.
 */

#include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

struct employee {

  char name[31];

  char address[101];

  int age;

  float salary;

};

typedef struct employee emp;

int compare_ages(const void *v1, const void *v2) {

    // Create two temp pointers for convenience, to ensure that the void pointers are interpreted correctly

  const emp     *e1 = v1;

  const emp     *e2 = v2;

  return e1->age - e2->age;

    // Note: could have been written: return ((emp *)v1)->age - ((emp *)v2)->age;

}

int compare_names(const void *v1, const void *v2) {

    //Create two temp pointers for convenience, to ensure that the void pointers are interpreted correctly
  const emp *e1 = v1;

  const emp *e2 = v2;

  return strcmp(e1->name, e2->name);

}

static void goodbye() {

  while (getchar() != '\n') {}
  printf("\nPress ENTER to exit: ");

  fflush(stdin);

  getchar();

}

main() {

  emp emps[] = {

    {"Bob",  "123 Hope St",   45, 45000.00},

    {"Tony", "124 Hope St",   99, 46000.00},

    {"Mary", "76 Banana Ave", 12, 20000.00},

    {"Sue",  "1000 Road Rd",  45, 90000.00},

    {"Fred", "32 Nowhere Rd", 51, 49000.00}

};

  int i;

  atexit(goodbye);

  qsort(emps, 5, sizeof emps[0], compare_ages);

  for (i = 0; i < 5; i++) {

    printf("%-10s is aged %d\n", emps[i].name, emps[i].age);
  }

  qsort(emps, 5, sizeof emps[0], compare_names);

  for (i = 0; i < 5; i++) {

    printf("%-10s\n", emps[i].name);

  }
}

Function Pointers


A function to pointer is a pointer variable that contains the address of a function. The return type and parameter types of the function must be declared in the declaration of a function pointer.

Here is an example:

	// The following two functions are similar
void read_emp(emp *e);
void print_emp(emp *e);

	// Below is the declaration of the function to pointer which is point to either of these functions
void (*func_ptr)(emp *e);

Note that the first two lines of above code are function prototypes. The last line is a variable declaration.

The statements below are the comparison between a function to pointer variable and a function prototype:

void (*func_ptr)(emp *e);	// function to pointer variable
void *func_ptr(emp *e);	// function prototype

Next post will be talking about the use of function pointers.