TwitterCounter for @bigclick_dean

dBlog.com.au

My Development Blog

Archive for the ‘ Featured ’ Category

Big Click Studios is a dynamic company based on the NSW Central Coast with a relaxing and innovative work environment.

Fantastic office just minutes from the beach and train station. You will be working on many of our current and upcoming web development projects all bursting at the seams begging for the right person to dig their teeth into!

Essentials:

  • PHP5 + MySQL
  • XHTML + Javascript (jQuery a bonus) & CSS
  • An eye for well structured code and clean database structures
  • Understanding of Object Orientated Programming

Bonuses:

  • CakePHP framework
  • AJAX
  • Flash / Actionscript 2 & 3

Personal characteristics:

  • Must be able to work as part of a team
  • Proactive involvement in the business (we work closely with all staff to provide a safe, fun and mentally challenging environment)
  • Strong communication skills (both written and spoken)
  • Xbox skills are not required but highly desired if you dont want to get whooped at lunch!

For more information please send an email to jobs@bigclick.com.au or give us a call on 1300 677 924.

Look forward to hearing from you soon!

Popularity: 1% [?]

While setting up some dedicated servers at the office I needed a quick and easy way to backup each server to an offsite location. After looking around for a while and trying some of the existing S3 backup scripts I couldn’t find anything that satisfied my needs (Apache htdocs & MySQL databases).

So after playing around a bit I decided to write up my own quick and dirty bash script. It doesn’t do incremental backups, rotation or any of that fancy stuff but it does everything I needed and I may expand on it later to remove any backups more than 30 days old but for now I will just delete them manually.

After scrounging around a bit I decided to go with the s3cmd command line tool to provide the access to the S3 service. If you use debian you can simply install it from the default repositories by running “apt-get install s3cmd”

You will need to configure s3cmd before using this script otherwise your backup transfers will fail. Follow the instructions over at http://s3tools.org/s3cmd

Now onto the script!

#!/bin/bash
unset PATH

# S3 VARIABLES
S3BUCKET=my-backups # S3 Bucket name

# LOCATION TO STORE BACKUPS WHILE PROCESSING
BACKUPDIR=./backup

# MYSQL DETAILS
MYSQLUSER=root
MYSQLPWD=password
MYSQLHOST=localhost

# APACHE FILES TO BACKUP
HTDOCS=/var/www

# PATH VARIABLES
MK=/bin/mkdir;
TAR=/bin/tar;
GZ=/bin/gzip;
RM=/bin/rm;
GREP=/bin/grep;
MYSQL=/usr/bin/mysql;
MYSQLDUMP=/usr/bin/mysqldump;
DATE=/bin/date;
FIND=/usr/bin/find;
S3CMD=/usr/bin/s3cmd

# OTHER VARIABLES
NOW=$($DATE +_%b_%d_%y);

#REMOVE EXISTING BACKUP DIRECTORY
$RM -Rf $BACKUPDIR$NOW

# Create new backup dir
$MK $BACKUPDIR$NOW

# FILE BACKUP
for i in $($FIND $HTDOCS/* -maxdepth 0 -type d -printf '%f\n'); do
   $TAR -czf $BACKUPDIR$NOW/httpdocs_$i.tar.gz $HTDOCS/$i;
done

# MYSQL BACKUP
for i in $(echo 'SHOW DATABASES;' | $MYSQL -u$MYSQLUSER -p$MYSQLPWD -h$MYSQLHOST|$GREP -v '^Database$'); do
  $MYSQLDUMP                                                    \
  -u$MYSQLUSER -p$MYSQLPWD -h$MYSQLHOST                         \
  -Q -c -C --add-drop-table --add-locks --quick --lock-tables   \
  $i | $GZ -9 > $BACKUPDIR$NOW/mysql_$i.sql.gz
done;

# ARCHIVE ALL FILES FROM THIS BACKUP
$TAR -czvf fullbackup$NOW.tar.gz $BACKUPDIR$NOW
$RM -Rf $BACKUPDIR$NOW

# UPLOAD THE BACKUP TO S3
$S3CMD put fullbackup$NOW.tar.gz s3://$S3BUCKET/fullbackup$NOW.tar.gz
$RM -Rf fullbackup$NOW.tar.gz

Simply put the above contents into a file (e.g. /root/s3backup.sh) and chmod it to 755.

Now to give it a test just execute the file s3backup.sh from the command line and check the output for errors and check your S3 account to make sure the file has arrived.

I know it’s not elegant, it’s not anything special but it does exactly what I need and I couldn’t find anything that did MySQL databases and Apache htdocs in the one foul swoop.

Good luck and any suggestions would be greatly appreciated.

Popularity: 1% [?]

Why did I do it?

While working on a client project I needed a way to heavily integrate with Twitter for an interactive competition. I could have built a quick and dirty script to do this but I knew that I would be dealing with more clients that wanted Twitter integration.

What did I do?

I built a CakePHP Component to access all the Twitter API features along with the Twitter Search API for Searching/Trending.

There are already some Twitter API components for CakePHP but they all had their own little bits that I didn’t like so I decided to whip one up and share it for everyone to use.

As the component is 1140 lines I wont be posting it here in the article, but you can view the source code here.

How does it all work?

There is nothing like a fully functioning example to show you how to use it! So I have built a quick replica of the Twitter homepage to give you a feel for it.

View the example first to see what we will be building, it is updated every refresh and everything is pulled straight from Twitter’s API.

First up you will need to put the Twitter Component into your /app/controllers/components/ folder and call it twitter.php, you can find the text version here or download the source files at the bottom of the page.

Now create a new controller called twitter_controller.php and put the following content into it. Don’t forget to change the {USERNAME} and {PASSWORD} place holders to your Twitter details.

<?php
/**
* Twitter Controller
*
* This class is used to manage twitter communication
*
* @version 0.1
* @author Dean Collins <dean@bigclick.com.au>
* @project dblog
*/
class TwitterController extends AppController {
	/**
	* Controller Name
	* @access public
	* @var string
	*/
	var $name = 'Twitter';

	/**
	* Components that are used in this controller
	* @access public
	* @var array
	*/
	var $components = array('Twitter');

	/**
	* Models that are used in this controller
	* @access public
	* @var array
	*/
  	var $uses = array();

	/**
	* Helpers
	* @access public
	* @var array
	*/
  	var $helpers = array('Text', 'Html');

	/**
	* Default action
	*
	* The index function is used as a default action, in this case it will replicate your twitter page
	*/
	function index() {
		$this->layout = 'twitter';
		$this->Twitter->username = '{USERNAME}';
        $this->Twitter->password = '{PASSWORD}';
		// Grab the recent activity
		$feed = $this->Twitter->statuses_friends_timeline();
		// Grab the users details
		$user_details = $this->Twitter->account_verify_credentials();
		// Get your friends
		$friends = $this->Twitter->statuses_friends();
		// Get your followers
		$followers = $this->Twitter->statuses_followers();

		$this->set('feed', $feed);
		$this->set('user_details', $user_details);
		$this->set('friends', $friends);
		$this->set('followers', $followers);
	}

}
?>

Now create a new layout in your /app/views/layouts/ called twitter.ctp and put the following content in:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>CakePHP/Twitter API Example</title>
<style type="text/css">
/* v1.0 | 20080212 */

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
	margin: 0;
	padding: 0;
	border: 0;
	outline: 0;
	font-size: 100%;
	vertical-align: baseline;
	background: transparent;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}

/* remember to define focus styles! */
:focus {
	outline: 0;
}

/* remember to highlight inserts somehow! */
ins {
	text-decoration: none;
}
del {
	text-decoration: line-through;
}

/* tables still need 'cellspacing="0"' in the markup */
table {
	border-collapse: collapse;
	border-spacing: 0;
}

</style>
</head>

<body>
<div style="top: 0px; left: 0px; width: 100%; height: 45px; padding-top: 20px; margin-bottom: 10px;">
	<div style="width: 800px; margin: 0 auto;">
    <h1 style="font-size: 24px;">CakePHP Twitter API Class Example</h1>
    </div>
</div>
<?php echo $content_for_layout; ?>
</body>
</html>

Finally create a new view under /app/views/twitter/ called index.ctp and put the following content in:

<style type="text/css">
body { font-size: 12px; font-family:Arial, Helvetica, sans-serif; background-image: url('<?php echo $user_details['User']['profile_background_image_url']; ?>'); background-attachment: fixed; background-repeat: no-repeat; }
.status_update img, .avatar { float: left; width: 48px; height: 48px; margin-right: 10px; }
.status_update { overflow: hidden; color: #333333; font-size: 12px; padding: 5px; border-bottom: 1px dashed #333; }

.status_update:hover { background-color: #CFF }

a {color: #0084B4;}
#lcol { width: 600px; border-right: 1px solid #333; float:left; }
#rcol { width: 180px; padding: 10px; float:left;}
#wrapper {width: 801px; margin: 0 auto; border: 1px solid #333; overflow: hidden; background-color: #FFFFFF}

#user_stats { margin-left: 15px; overflow: hidden; }

#user_stats a { color: #333333; display: block; float: left; font-size: 20px; text-align:center; text-decoration:none; background-color: transparent;}

#user_stats a span { font-size: 12px; color: #0084B4; }

#profile_title { font-size: 18px; margin-bottom: 10px; overflow: hidden; }

.avatar_small { width: 24px; height: 24px; }

.avatar_list { list-style: none; list-style-type:none; overflow: hidden }

.avatar_list li { float: left; }

#rcol h2 { font-size: 18px; padding: 5px; margin-bottom: 5px; margin-top: 10px; }
</style>
<div id="wrapper">
<div id="lcol">
    <ol>
    <?php foreach($feed['Statuses']['Status'] as $status) { ?>
    <li class="status_update">
    <img src="<?php echo $status['User']['profile_image_url']; ?>">
    <p><?php echo $status['text']; ?></p>
    </li>
    <?php } ?>
    </ol>
</div>
<div id="rcol" style="background-color: #<?php echo $user_details['User']['profile_sidebar_fill_color']; ?>">
    <div id="profile_title">
        <img class="avatar" src="<?php echo $user_details['User']['profile_image_url']; ?>"/>
        <?php echo $user_details['User']['screen_name']; ?>
   	</div>
    <strong>Name</strong> <?php echo $user_details['User']['name']; ?><br/>
    <strong>Location</strong> <?php echo $user_details['User']['location']; ?><br/>
    <strong>Web</strong> <a href="<?php echo $user_details['User']['url']; ?>"><?php echo $text->truncate($user_details['User']['url'], 20, '...'); ?></a><br/>
    <strong>Bio</strong> <?php echo $user_details['User']['description']; ?><br/>
    <div id="user_stats">
        <a href=""><?php echo $user_details['User']['friends_count']; ?><br/><span>following</span></a>
        <a href="" style="margin-left: 20px;"><?php echo $user_details['User']['followers_count']; ?><br/><span>followers</span></a>
    </div>
    <h2>Followers</h2>
    <ul class="avatar_list">
    	<?php foreach($followers['Users']['User'] as $follower) { ?>
        	<li><a href="http://www.twitter.com/<?php echo $follower['screen_name']; ?>/" target="_blank"><img alt="<?php echo $follower['screen_name']; ?>" width="24" height="24" class="avatar_small" src="<?php echo $follower['profile_image_url']; ?>"/></a></li>
        <?php } ?>
    </ul>

    <h2>Following</h2>
    <ul class="avatar_list">
    	<?php foreach($friends['Users']['User'] as $follower) { ?>
        	<li><a href="http://www.twitter.com/<?php echo $follower['screen_name']; ?>/" target="_blank"><img alt="<?php echo $follower['screen_name']; ?>" width="24" height="24" class="avatar_small" src="<?php echo $follower['profile_image_url']; ?>"/></a></li>
        <?php } ?>
    </ul>
</div>
</div>

And that’s it! You can head to http://yourcakeinstall.com/twitter and you should see a Twitter-like page with all your details with friends, followers, tweets, etc.

You can see my example over here

There is ALOT you can do with the data from Twitter so please let me know if you build something using this component and I will chuck a link up here for you.

Download the Source Files

You can download the source files, including the above example below.

CakePHP/Twitter API Component Download

Don’t forget to follow me on twitter and subscribe to my RSS to stay in the loop.

Popularity: 1% [?]

In this installment we will be creating the “framework” for our application, first up we will be creating our UITabBarController and then we will add some ViewControllers to represent our different views.

1. Create a “Window-Based” application template

I had originally intended to create the application based on a “Navigation-Based” application template but now I have decided to create everything from scratch and not use Interface Builder. So if you have already completed part 2 then I suggest you go back there and follow the instructions to create the new “Window-Based” application template.

2. Setting up the UITabBarController and its delegate

Open up RSSReaderAppDelegate.h and edit the code to look like below


#import <UIKit/UIKit.h>

@interface RSSReaderAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) UITabBarController *tabBarController;

@end

What we have done here is added the UITabBarControllerDelegate and created a UITabBarController instance called tabBarController.

Now you will need to open up RSSReaderAppDelegate.m and synthesize the tabBarController instance and alter the applicationDidFinishLaunching function to look like this


- (void)applicationDidFinishLaunching:(UIApplication *)application {

tabBarController = [[UITabBarController alloc] initWithNibName:nil bundle:nil];

// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];

// Override point for customization after application launch
[window makeKeyAndVisible];
}

This will allocate and init the UITabBarController and then add it to the window (we haven’t added any buttons yet, but we will do this shortly).

If you run your application now you should see the UITabBar at the bottom of the window like so:
UITabBar with no buttons

3. Creating our UINavigationController

Right Click on the Classes folder in the left hand column and click Add > New File… , the following window will appear
XCode: Add new File

Now choose UIViewController subclass and click next, now name the class MainViewController.m and click Finish.

You should now have a MainViewController.h and a MainViewController.m file in your Classes folder. Open up MainViewController.h and edit its contents to below:


#import <UIKit/UIKit.h>

@interface MainViewController : UINavigationController {
UINavigationController *navigationController;
}

@property (nonatomic, retain) UINavigationController *navigationController;

@end

Notice we have changed the subclass from UIViewController to UINavigationController and we have added a UINavigationController instance.

Now open up MainViewController.m and edit its contents to below:


#import "MainViewController.h"

@implementation MainViewController

@synthesize navigationController;

- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"Main View Did Load: %@", self.tabBarItem.title);
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}

- (void)dealloc {
[super dealloc];
}

@end

All we have done here is synthesized the navigationController instance and put a NSLog call to display when the controller is created and what its TabBar item title was when it was created.

If you run the application now you wont see anything different, this is because we haven't added anything to the UITabBarController yet. To add the buttons you will need to open up the RSSReaderAppDelegate.m file and edit the applicationDidFinishLaunching function to look like below:


- (void)applicationDidFinishLaunching:(UIApplication *)application {

tabBarController = [[UITabBarController alloc] initWithNibName:nil bundle:nil];

// Create instances of the MainViewController for the 4 TabBar buttons
MainViewController *viewController1 = [[[MainViewController alloc] initWithNibName:nil bundle:nil] autorelease];
viewController1.tabBarItem.title = @"Browse All";
MainViewController *viewController2 = [[[MainViewController alloc] initWithNibName:nil bundle:nil] autorelease];
viewController2.tabBarItem.title = @"Most Recent";
MainViewController *viewController3 = [[[MainViewController alloc] initWithNibName:nil bundle:nil] autorelease];
viewController3.tabBarItem.title = @"Favourites";
MainViewController *viewController4 = [[[MainViewController alloc] initWithNibName:nil bundle:nil] autorelease];
viewController4.tabBarItem.title = @"Settings";
tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, viewController3, viewController4, nil];

// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];

// Override point for customization after application launch
[window makeKeyAndVisible];
}

What we are doing here is creating 4 instances of the MainViewController and setting the tabBarItem title (this displays below TabBar icon). Once we have created all four of the View Controllers we add them to the tabBarController by setting its viewControllers property to an array containing the pointers for our 4 View Controllers. Remember that you need to have a nil value at the end of the array to indicate the last element.

If you run your application now you should see 4 TabBar items with the titles we have assigned them above. You will also notice that we have a Navigation bar at the top of our window, as we don't have a UITableView setup yet the Navigation bar will just be blank.

iPhone SDK: RSS Reader - TabBar & NavigationController working

4. Setting up our UITableViews

Now for starters we are going to need 4 UITableViewControllers for our Browse, Recent, Favourites and Settings Tabs. We will start with the stock standard ones and customize them as we go along.

Right Click the Classes folder in the left hand column and click Add > New File...
Select UITableViewController subclass and click Next
Call the first one BrowseViewController.m and then click Finish
Repeat these steps and create a RecentViewController, FavouritesViewController and SettingsViewController

Now that we have all our stock standard UITableViewControllers created we have to connect them up, we will be doing this in the MainViewController.m file, so open it up and edit its viewDidLoad function to below:


- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"Main View Did Load: %@", self.tabBarItem.title);
if(self.tabBarItem.title == @"Browse All") {
BrowseViewController *browseViewController = [[BrowseViewController alloc] init];
[self pushViewController:browseViewController animated:YES];
[browseViewController release];
} else if (self.tabBarItem.title == @"Most Recent") {
RecentViewController *recentViewController = [[RecentViewController alloc] init];
[self pushViewController:recentViewController animated:YES];
[recentViewController release];
} else if (self.tabBarItem.title == @"Favourites") {
FavouritesViewController *favouritesViewController = [[FavouritesViewController alloc] init];
[self pushViewController:favouritesViewController animated:YES];
[favouritesViewController release];
} else if (self.tabBarItem.title == @"Settings") {
SettingsViewController *settingsViewController = [[SettingsViewController alloc] init];
[self pushViewController:settingsViewController animated:YES];
[settingsViewController release];
}

}

Now this may not be the most traditional method and isn't very good for massive applications that use heaps of view controllers, etc but it worked fine for my needs and meant I only needed one UINavigationController (MainViewController). What it does is it checks the title of the TabBar item that it is linked to, it then decides which UITableViewController to push into view.

Also don't forget to #import the four new header files


#import "BrowseViewController.h"
#import "RecentViewController.h"
#import "FavouritesViewController.h"
#import "SettingsViewController.h"

If you run your application now you will wee that we have a UITableView visible on each of the TabBar items, but we currently cant tell which one is which as they all look the same.

5. Identifying and Customising our UITableViews

Starting with our BrowseViewController we want to open up the BrowseViewController.m file and alter it's viewDidLoad function to below:


- (void)viewDidLoad {
[super viewDidLoad];

self.title = @"Browse All";
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:nil];
}

We have set the title to "Browse All" and we have added a button to the right hand side of the navigation bar, this button is an add button (as indicated by UIBarButtonSystemItemAdd) and currently its action is set to nil, in the future we will connect this up to an UIActionSheet.

Now go through the other three controllers (RecentViewController, FavouritesViewController and SettingsController) and just set the title, not the rightBarButtonItem!

If you run your application now you should be able to navigate through it and see the title change and on the Browse All tab you should see an add button at the top right, although it wont do anything when you press it.

Browse All TabMost Recent TabFavourites TabSettings Tab

6. Download the Project Files

Click Here to download my version of the Project files, you can use these to work your way through any problems or even to work backwards to see how I do things.

7. Whats Next?

In the next installment we will be creating our SQLite database and adding some feeds and groups, we will also be setting up the BrowseViewController to handle multiple levels of groups with only one view (Drilldown) and we will also be looking at storing images in a SQLite database with a BLOB field.

PLEASE CLICK HERE TO RE-TWEET THIS TUTORIAL

Please do anything you can to spread these tutorials around as the more people that read the faster I will write tutorials!

Popularity: 15% [?]