Juicing Up Photo Viewing Experience: Part I

on this blog, on your wordpress site, or anywhere else. This series is a result of my recent craze with scripting/programming and photo ideas.

Screenshot of Fotobook Highslide

Previous Next Close
Fotobook Highslide - Mash up of WordPress, Facebook Photos & Highslide JS

1. Photo Gallery
I tried a couple of wordpress plugins in the past: Gallery2, Simple Extended Gallery, Flickr….

They were perhaps good, but perhaps complex, lacking and I didn’t seem to like it. Then I created PhotoZip and even though Photozip plugin had its short comings (eg. perhaps a little slow due to batch processing), I’m glad Tim have the interest to improve it so much better than I would.

It is only recently I found out about Aaron Harp’s Fotobook, an integration/mashups of Facebook’s photos into your blog. So I tried it, and it works.

The integration is good (since I use facebook too), the layout neat, the configuration all done with much ease. It seems like it was something I tried looking so hard before, now that I found it, I love it. My photo gallery can be viewed by clicking on the Photos tab.

2. Highslide
Tim’s improved PhotoZip supports LightBox, so does Fotobook. No doubt it gives great effect and I like it too when used appropriately. Even my cousin’s portfolio uses it to enhance viewing experiences.

However, a reason why I don’t use it? Perhaps it was due to some negativity when I experienced it on some sites. But when I come across the Highslide javascript library, I thought I would use it for the following reason
1. At the first impression it reminds of LightBox- to expand an image in the same window.
2. However, unlike Lightbox, it is less obstructive. The background is not grayed out, and window can still scroll, and the expanded image can be dragged around.
3. It seems more reactive.

Not only it good to find the right tool for the right job, it good to find the best package available. So I’m using Highslide WordPress plugin. Since fotobook was written in a way it was simple to customise it, I created a style/theme similar to Aaron’s lightbox style, except it works with highslide. Check out one of my gallery for example.

(Tip: You can use arrow buttons on your keyboard to navigate through the photos. You can also click/expand more than one photo at a time too.)

Click here to download Highlight Style for Fotobook.

Instructions:
Ensure you have Fotobook and Highslide plugin working.
Copy the highslide folder into fotobook styles folder
(eg. /wordpress/wp-content/plugins/fotobook/styles)
Select the highslide style under fotobook options.
View your photo gallery, test and enjoy!

Blog Posts on a Timeline

Its 2008, so wishing all readers here a very happy new year!

Yesterday, I touched about glancing back at a previous year (2007) , and one good way is to retrieve all the posts on your blog and place visualise it on a timeline. Of course there are other ways, say looking and sharing photo albums with friends could be a better way to bring back memories.

My Blog on the Timeline

I revisited Dandelife (A Social Biography Network?), and found that they have made more features and progress, compared to the last time I tried using it. Some features include importing “life streams” from flickr, facebook, blogs, feeds etc… anyway I didn’t manage to import my blog so I moved on.

Next I tired SIMILE Timeline plugin for WordPress. Pretty good it seems, but I encountered couple of problems which i didn’t bother to troubleshoot and fix much. I considered implementing my own wordpress plugin when I got the idea to create a client which uses MetaWeblog API, so that it can work not only for my blog, but any wordpress blogs, blogger sites etc.

I will use the metaWeblog.getRecentPosts method to retrieve the post from the webservice. Since metaweblogapi is based on xmlrpc, I used the library phpxmlrpc. The data returned is then formatted as timeline xml to be used the timeline api (in my case I chose to truncate blog contents too). Pretty simple right?

Here’s my source code which I glued together quickly, isn’t too pretty, but works dandy for me. I’ve placed the script online, so you may want to try it.


<?php
/* by http://zz85.is-a-geek.com/ 31 December 2007 */
session_start();
if ($_POST['login']) {
	$reponse = blogconnect ($_POST['blogaddr'],1, $_POST['username'],$_POST['password']);
	if ($reponse->errno=="0") {
		$_SESSION['blogaddr'] = $_POST['blogaddr'];
		$_SESSION['posts'] = $_POST['posts'];
		$_SESSION['username'] = $_POST['username'];
		$_SESSION['password'] = $_POST['password'];
		showhtml();
	} else {
		echo "login failed";
		showform();
	}
} elseif ($_GET['js']) {
	$_SESSION['username'].$_SESSION['password'];
	printxml(blogconnect($_SESSION['blogaddr'],$_SESSION['posts'], $_SESSION['username'],$_SESSION['password'])); 
	exit;
}else {
	showform();
}

function blogconnect($link, $posts, $username, $password) {
	//requires xmlrpc.inc from http://phpxmlrpc.sourceforge.net/
	require_once('lib/xmlrpc.inc');
	
	// Using metaWeblogApi http://www.xmlrpc.com/metaWeblogApi	
	$client = new xmlrpc_client($link);
	 $client->return_type = 'phpvals';
	 //$client->setDebug(1);
		
	 $params[] = new xmlrpcval("n/a");
	$params[] = new xmlrpcval($username);            //your wordpress login
	$params[] = new xmlrpcval($password);
	$params[] = new xmlrpcval($posts);  
	 $msg    = new xmlrpcmsg("metaWeblog.getRecentPosts",$params);
	$response = $client->send($msg);
	return $response;
}
function printxml($response) {
	header('Content-type: text/xml; charset=utf-8');
	echo "<data date-time-format=\"iso8601\">";
	foreach ($response->val as $entry) {
		/*
		['dateCreated']
		['userid']
		['postid']
		['description'] 
		['title'] 
		['link']
		['permaLink'] 
		['categories'] 
		['mt_keywords']
		['wp_author_display_name']
		['date_created_gmt'] -8
		*/
		
		$description = htmlentities (substr($entry['description'],0,255)."...");
		?>
<event 
        start="<?=$entry['dateCreated'];?>"
        end="<?=$entry['dateCreated'];?>"
	link="<?=$entry['link'];?>"
        title="<?=htmlentities($entry['title']);?>"
        >
	<?=htmlentities ($description);?>
        <?=htmlentities('<br/>by '.$entry['wp_author_display_name'].'');?>
</event>
		<?php
	}
	echo "</data>";
}

function showform(){
?>
<form method="post">
Blog Address: <input name="blogaddr" value="http://yoursite/blog/xmlrpc.php" size="40"/><br/>
No. of posts: <input name="posts" value="100" /><br/>
Username: <input name="username" /><br/>
Password: <input name="password" type="password" /><br/>
<input name="login" type="hidden" value="1"/>
<input type="submit"/>
</form>
<a href="http://zz85.is-a-geek.com/">http://zz85.is-a-geek.com/</a>
<?php } 

function showhtml() {
?>
<html>
  <head>
  <title>Wordpress (MetaWeblog) API and Timeline API Integration</title>
   <link rel='stylesheet' href='http://simile.mit.edu/timeline/docs/styles.css' type='text/css' />
    <script src="http://simile.mit.edu/timeline/api/timeline-api.js" type="text/javascript"></script>
    <script>
    	var tl;
	var eventSource = new Timeline.DefaultEventSource();
	
	function onLoad() {
		createTimeline();
	}

function createTimeline() {
  var bandInfos = [
      
   Timeline.createBandInfo({
        width:          "25%", 
	//timeZone: 8,
	eventSource:    eventSource,
        intervalUnit:   Timeline.DateTime.DAY, 
        intervalPixels: 50
    }),
    Timeline.createBandInfo({
	showEventText:  true,
	eventSource:    eventSource,
	width:          "60%", 
        intervalUnit:   Timeline.DateTime.WEEK, 
        intervalPixels: 100
    }),
    Timeline.createBandInfo({
        width:          "15%",
	eventSource:    eventSource,
	showEventText:  false,
        intervalUnit:   Timeline.DateTime.MONTH, 
        intervalPixels: 95
    }),

  ];
  
  // sync bands
  bandInfos[1].syncWith = 0;
  bandInfos[1].highlight = true;
  bandInfos[2].syncWith = 1;
  bandInfos[2].highlight = true;
  
  tl = Timeline.create(document.getElementById("my-timeline"), bandInfos);

  Timeline.loadXML("<?php echo $PHP_SELF; ?>?js=1", function(xml, url) { eventSource.loadXML(xml, url); });
}

var resizeTimerID = null;
function onResize() {
    if (resizeTimerID == null) {
        resizeTimerID = window.setTimeout(function() {
            resizeTimerID = null;
            tl.layout();
        }, 500);
    }
}

  </script>
  </head>
  <body onload="onLoad();" onresize="onResize();">
  	<h2>Laying Out a Year (2007) Full of Blog Posts on the Timeline</h2>
	Using Simile Timeline Library, WordPress API/MetaWeblog API, and PHP to translate that into Timeline XML. <br/> 
	<div id="my-timeline" style="height:450px; border: 1px solid #aaa"></div>
	<a href="http://zz85.is-a-geek.com/">http://zz85.is-a-geek.com/</a>
  </body>
</html>
<?php } ?>

So now, I can have twitter and blog posts displayed on the timeline. If I have the time, calendars and metadata would be next. But there’s also too many other data sources around. Emails- run a search on gmail. On handphone, view the calendar data and smses for a year. Photos: Run time view in Picasa. Diary: read. Gps: Color tag them on googlemaps? Too many! so I’ll be satisfied with the blogs posts on the timeline for now.

Happy revisiting your posts!

Timeless Belt Of Time: How I Integrated Twitter in Timeline

using JSON, PHP, CURL, JS, and of course HTML, and APIs of Simile Timeline and Twitter.

Timeline Twitter Mash up
Looks a little like a seismograph?

My first little personal project in this year was dealing with time, used by myself and view daily by my colleges in TAD. Later in the year, I brainstormed several other ideas that I hope to implement as a web 2.0 application. I stumbled on the Simile Timeline project earlier, thought it was a good idea, but never tried it until today. But it was also the fun using Twitter that sparked the interest to use Timeline and to integrate them.

However, given the large interest in twitter and mash ups, I would have expected someone else to have done before. Still there are handful of resources with the knowledge required to hack the pieces together. So let me outline what I did.

1. Prepare a php script to call Twitter’s API to retrieve Twitter posts using CURL. To do as little coding as possible, I decided to use JSON format (over XML), pass it self as an object into the (html) client’s javascript method.
2. The javascript method would iterate each of twitter’s data then generate the events in Timeline’s format.
3. Initialize and run Timeline’s API to render.

twitter.php The server side script.


<?php
/* 29 Dec 2007, http://zz85.is-a-geek.com/ */
// Edit your twitter's username and password 
$username = 'USERNAME';
$password = 'PASSWORD'; 

// The twitter API address
//$url = 'http://twitter.com/account/archive.json'; // Each archive API call could return 80 statuses, 
								// but there seem to be an error on Twitter's side so I'll use 
								// the User timeline call which returns only the last 20 posts.

$url = 'http://twitter.com/statuses/user_timeline.json';

$curl_handle = curl_init();
curl_setopt($curl_handle, CURLOPT_URL, "$url");
curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_USERPWD, "$username:$password");
$buffer = curl_exec($curl_handle);
curl_close($curl_handle);

echo "timeline_data($buffer);"; // timeline_data is the javascript method to be execute
?>

time.html The Client side html

<html>
  <head>
  <title>Timeline API and Twitter API Integration</title>
   <link rel='stylesheet' href='http://simile.mit.edu/timeline/docs/styles.css' type='text/css' />
    <script src="http://simile.mit.edu/timeline/api/timeline-api.js" type="text/javascript"></script>
    <script>
    	var tl;
	var eventSource = new Timeline.DefaultEventSource();
	
	function onLoad() {
		var scriptTag = document.createElement('script');
		scriptTag.src = "http://CHANGEME_DOMAIN/twitter.php"; // Change to URL of your php script
		document.body.appendChild(scriptTag); // Runs the contents from the URL being called as javascript
	}

function createTimeline() {
  var bandInfos = [
      
   Timeline.createBandInfo({
        width:          "65%", 
	timeZone: 8, // I have to adjust the time as I live in GMT +8
	eventSource:    eventSource,
        intervalUnit:   Timeline.DateTime.HOUR, 
        intervalPixels: 80
    }),
    Timeline.createBandInfo({
	    showEventText:  false,
	eventSource:    eventSource,
	width:          "20%", 
        intervalUnit:   Timeline.DateTime.DAY, 
        intervalPixels: 70
    }),
    Timeline.createBandInfo({
        width:          "15%",
	showEventText:  false,
        intervalUnit:   Timeline.DateTime.MONTH, 
        intervalPixels: 100
    }),

  ];
  
  // sync bands
  bandInfos[1].syncWith = 0;
  bandInfos[1].highlight = true;
  bandInfos[2].syncWith = 1;
  bandInfos[2].highlight = true;
  
  tl = Timeline.create(document.getElementById("my-timeline"), bandInfos);
   //tl.loadJSON("cubism.js", function(json, url) { eventSource.loadJSON(json, url); });
}

var resizeTimerID = null;
function onResize() {
    if (resizeTimerID == null) {
        resizeTimerID = window.setTimeout(function() {
            resizeTimerID = null;
            tl.layout();
        }, 500);
    }
}





function timeline_data(tjson) { // method called after response of twitter.php is exectured
	for (entries in tjson) {
		 var dateEvent = new Date(tjson[entries]["created_at"]);
		 var urlbase = 'http://twitter.com/' ;
		var evt = new Timeline.DefaultEventSource.Event(
		dateEvent, //start
		dateEvent, //end
		dateEvent, //latestStart
		dateEvent, //earliestEnd
		 true, //instant
		 tjson[entries]["text"], //text
		 '<a href="'+ urlbase + tjson[entries]["user"]["name"] + '/">' +
		 '<img src="' + tjson[entries]["user"]["profile_image_url"] + '" />'
		 + tjson[entries]["user"]["name"] +'</a>' + ' '
		  + tjson[entries]["text"] +
		 '<br /><a href="' + urlbase + 'statuses/' +tjson[entries]["id"]+'">Source:</a>'+ tjson[entries]["source"] + ''
		 //description
		);
		eventSource.add(evt);
	}
	createTimeline();
 }    </script>
  </head>
  <body onload="onLoad();" onresize="onResize();">
  	<h2>Zz85 Integration Test of Timeline API with Twitter API</h2>
	<div id="my-timeline" style="height:450px; border: 1px solid #aaa"></div>
	<br />version 1 by <a href="http://zz85.is-a-geek.com/">http://zz85.is-a-geek.com/</a>
  </body>
</html>

Well, I hope this would work for you, or at least help you to do something better. At least if you managed to do what I did, you would be able to visualise what you were doing on the dynamic scrollable timeline. Of course, the timeline javascript library issnt perfect, and I wish there were features like: adding events by clicking on the timeline, dragging the duration, zooming in&out and dragging the events around. Anyway I have some ideas, that I’m likely not to do it, but its implementable.

  • Integrate Photos eg. Flickr/Fackbook + Blogs + MAps + …
  • Integrate Calendars (eg. Google Calendars)…
  • Automatic Widening/Narrowing
  • Import and usage of own database with metadata
  • Layered Rows for Different events.
  • Integrate with other time applications like countdown counter
  • Integrate ToDo List

Have timeless fun! Drop me a note if you manage to do something satisfying after reading this article, or if you have some other cool ideas too =)

Further Readings

  1. Tutorial on using Timeline
  2. About JSON
  3. Posting to Twitter using PHP and CURL
  4. twitter api
  5. Google’s method of dynamic json data import
  6. a json inspector
  7. Creating timeline from (blog) feeds

Activity & Status Streams

Perhaps some keep a journal so they can remember what they have done in the past. Perhaps many nowadays use a blog for that purpose too. Twitter, which appeared in my previous post, a social networking site based mainly on activity streams could now be the synonym for “what am/was/are I/you doing”.

Twitter Ninja

Twitter’s API allows many implementation of getting twitter service, eg. this twitter balloon.

A similar feature exist in Facebook, and is perhaps the more popular among many is to announce their status or what they are doing. Recently I read that the first thing one would do after a relationship break off is to change their status on Facebook. Perhaps you are not that extreme, but might still be guilty of complaining, or showing off via your online messaging nick, status or personal message.

Talking about streams, no one can deny the power of RSS feeds, whether its a blog, twitter, or facebook, they all have them. And my preferred method for reading blogs, and my favorites sites.

And lastly, even Google must have realise the potential of these lifestreaming activities and acquired Twitter’s competitor Jaiku. Even though there are already a couple of Google Services eg. Maps/Earth + Twitter Mashups, it would be interesting to see what Google has in store for all of us (perhaps integrate gcalendars too).

Visitors Around The World

Alright, for a little fun with toys here’s a tracker which shows where in the world, my web visitors are from on the world map. If you have noticed too, the wordpress engine, plugins and themes I’m using now are updated.

Here’s the statistics page and map from http://whos.amung.us/.


zz85.is-a-geek.com

In my last post, I mentioned that my email address needs to be updated (for those who emailed >2 years ago). This time zz85.is.dreaming.org couldn’t redirect to this blog and needs updating.

I tried to login dyndns to check my dynamic domains account and weirdly my account has been deleted. Anyway it seems that current dreaming.org network would be terminating its domain.

So I re-sign up and got http://zz85.is-a-geek.com as a url shortcut. Yes, for those who bookmarked this site, http://www.lab4games.net/zz85/blog/ still works. One last exam paper to go, taking another break now!

Lights Off, Laptop!

Based on our experiences use gadgets like handphones, digital cameras, DS etc, we probably guessed bulked of the batteries usage went into the LCD screen.

Personally I find little electricity used in turning the colours of the pixels, but much in powering the backlight. A digital watch I had exceeded its estimated battery life without its light used often. The DS Lite new brightness levels consumes the battery much faster than if you use the less bright options. When I use the DS for music listening, closing the lid usually turns off the LCD and allow much longer battery stamina. Digital cameras usually have an option for switching on and off the LCD screens, but what about laptops?

Let me go through the different options.

High-end models would have the LCD poweroff button: Hit “Fn+Battery Key”. If you don’t, you could dim it manually hitting the brightness buttons.

Why not close the laptop lid? Remember the reason why we just want just the lights of is for the computer to go doing what it needs to (play some music, transferring files using wifi, do some virus scan etc). Closing the lid but default usually means suspend, sleep or hibernate, so you need to change the power saving schemes if you like the lid shutting action.

Windows have this Blank screensaver which turns the screen black. Or you could download the freeware Power Dimmer which mimics iBooks screen-fading-energy-saving feature. Take note that these 2 doesn’t turn your screen off, only changing the screen black so the lights in them are still on. Anyway a tip for those who like to turn on their screensavers by demand, create a shortcut (on the desktop) to the screensaver file, double click it or assign a hot shortcut key to run them.

Next, in the windows energy saving section, you could specify screens to turn off after a period of time. Good, and I usually set it @ 2 minutes and power dimmer @ 1 minute. However, your media player may forbid the system entering power saving while you are listening to music.

Here’s more cool tools to the field. NirCmd is a command line based swiss knife for windows. Type nircmd.exe monitor off or create a shortcut for this command to turn off your screen at demand.

Need a easier software? There’s a software called MonOff but I’ve not tired it. However, my favorite software for controlling windows shutdowns called PowerOff also does the job for screens. Its a very small, no-installations-needed file, and after running it you task it to poweroff your screen/windows immediately or a specific time, or decide later at the icon-tray.

Further readings: 1
2

Lights off, sleep tight, keep dreaming, so don’t drain my battery, screen, eyesight and brain cycles too much.

Design My Bedroom with Simple 3D

Ever wanted to re-design your bedroom on your computer?

IKEA Kitchen Planner is a free and easy software to plan your kitchen and furnishing. At Jordan’s Furniture you could use their online flash software to design your room layout with different furnitures.

There are perhaps 1001 commercial 3D products out there (a friend recently recommended SolidWorks), but for free, open source 3d software, a list has always been blender 3d, povray etc.

This time, I tried out Google’s free 3D software, SketchUp. The last time, I used 3DS max, so relatively SketchUp looks simple and lacking, and it took me some time to adjust using its interface, shortcuts, so on. It wouldn’t take long to find out that this software could do alot (like almost all 3d software, limited only by imagination), if only you knew how. Before you could unleash its power, most users would properly want to view its guides or online video tutorials to get started.

I always relate 3d modeling to molding or sculpturing, but SketchUp is unique with its powerful Pencil tool, which makes modeling 3d like drawing. It could switch between and many different views easily, and here are some renders I have done of my room today.

My Room

Plain Top View

Bedroom Plan with X-Ray Drawing View

Coloured Perspective

View At the Door

Computer Generated Sketches Style

Autocad Style

Monochrome

Textured view

In real life…

Messed Room Photo

Not so simple or neat :X

Anyway there’s a Slashdot.org discussion on 3D software for home planning, and as one user has pointed out, the best method perhaps is still pencil and paper.

Online Diary

Weather: Cloudy

I stumbled across this chinese webpage (when searching some chinese terms) where user can write their diary online.

The webpage may not be well designed (visually), yet I found it very interesting because of the simple way of presenting its data/facts.

As a online diary, user selects the mood they feel for a particular post, a sad feeling? a happy feeling, a loving feeling so on. An icon shows the weather for the date- sunny, rainy, so on. The post made displayed on a background with letter lines, and writers could insert pictures or icons. As I peep around some of the posts, they are surprising short- the chinese language makes it possible to express alot, in detailed, in a few words.

I’m not a one who writes diaries or journals (even when our teachers wanted us too), but the site has gave me the feel and look of a diary. Although I suspect there would be plenty of better, nice and good webpages which provides dairy writing service, I’m not searching for them currently, but bloggers who blog entirely in the diary style might be interested to look for sites as such.

Ubuntu Tweaks (Part 2 – Repository and Packaging)

Continued from Part 1 of my series on Ubuntu tweaking.

When I first planned to run Ubuntu 6.10 “Edgy Eft”, many reviews on the net showed that not everyone is happy, some whom might think its not edgy enough, some who had their systems broken because they tried to upgrade.

Remember one of my reason I installed Ubuntu? The nature of Ubuntu and its community makes it easy to use, customise and repair the system. In this post, I would show ways to play with your ubuntu system- using apt, guides on the net, and using some other packaging or unified installation software.

Ubuntu

Apts
Apt (Advanced Packaging Tool) was perhaps the reason why many chose Debian. The Ubuntu repositories could then be the very reason that others like me chose ubuntu. Apt-get, Aptitude are very useful and powerful commands to play with. However after trying Ubuntu Synaptic Package Manager for time, I love it for these reasons:

- It has a gui (Graphical User Interface) for those who wouldn’t even touch a shell.
- Its really easy to add, disable, delete sources
- Easy to find, mark and install many packages at one go
- Download packages simultaneously, with ability to resume, making downloads faster
- Notifies you of updates and easy to access via its tray icon.

Even now I use Synaptic a lot and recommend it, apt-get and aptitude are still as important and good to learn and use. Read about aptitude versus apt-get

Finding Ubuntu Repositories
Having nice repository sources is perhaps all you need for a long time. Using these packages, I find that it is even easier to search and install software compared to Windows.

1st, you can uncomment the less official but supported ubuntu sources from /etc/sources.list or preferably do so in Synaptic. Next try out source-o-matic a Ubuntu source.list generator which produces a source list based on selection of criteria you chose. Ubuntu geek has a source list for Edgy Eft which is worth taking a look. Lastly for sources, for the more adventurous, I would recommend TreviƱo source list which including many packages compiled by him.

Other Debian Packages
Automatix is an Automated GUI installation script which installs the common software people demands. Read here as their official site seems down.

When using lots of “super-cow powers” apts, dun forget they are basically Debian packages. Finding and downloading debian packages is a very simple way to install applications. See GetDeb – Click And Run – Software Portal

Other Packaging
One of Apt/Deb uses is that they are a solution to dependencies. However, it is not the only solution around. Many package management exists for other distros – portage (emerge) for Gentoo, packman for ArkLinux, rpm for Redhat… There are some which are distro independent.

Klik, its another innovative web-based click and install software manager. From its webpage, “Klik strives to be the easiest way to download and run software, without installation”. I love the way you install Klik, with at most 2 lines (in user mode without the dollar signs):


$ sudo apt-get install binutils libstdc++5 rpm gnome-about # for (k)Ubuntu
$ wget klik.atekon.de/client/install -O -|sh

Autopackage – Easy Linux Software Installations for both users and developers. “Autopackage doesn’t need to be downloaded or installed. When you install your first package, Autopackage will install itself automatically.” Check out their package listings

Zero Install system is a caching network filesystem, to make software installation completely automatic. This decentralised installation systems has been made to work with the Rox Desktop

Lastly, if you were to experiment building from sources, you would like to work with the command, esp. tar, cvs, svn, git. CVS (Concurrent Versioning System), SVN (Subversion), GIT(distributed revision control file system project) are also repositories system at a different level.

CheckInstall is a software which helps you keep track of installations done using make install, and creates distro based uninstallations like dpkg on debian.

Welcome to the addictive world of Linux software.