Miscellaneous

You are currently browsing the archive for the Miscellaneous category.

Conwitter is a Twitter client for Google Chrome web browser. You can download here.

Reason 1: It has some awesome features

Conwitter lets you see replies grouped together as conversations, shows thumbnails of shared images, etc. Since I started testing the extension, I’ve missed these features every time I switched to a different client. The “conversation” feature with the Twitter streaming API support is pretty cool, that you can see discussions of your friends with others. Since these are bundled together it won’t be a distraction.

Reason 2: Customizable

It is highly customizable from the colors to dimensions of the extension. For example, if you are working on a low resolution you can reduce the width and height of the extension to neatly fit into your screen.

Reason 3: Streaming API

This is one of the first Twitter clients to implement the Streaming API. With streaming, you get updates instantaneously – you don’t have to set a update time and wait for few minutes to receive the recent updates. Also, with the streaming API you get tweets from tweeple you don’t follow if anyone you’re following is mentioned. For example, if one of your friends tweeted about a new movie, you’d be able to see replies to him from all around the world. However, this can be annoying sometimes, e.g. if you don’t like that movie; but since Conwitter is grouping all the replies together it is not much of a pain. Anyway you can disable the use of streaming API if you wish.

Reason 4: New features popping in frequently

New features are being added to Conwitter frequently. For instance, in the past few days, there had been a new feature introduced daily.

Reason 5: Conwitter is shaped by your ideas

…and the best thing is most of the new features are products of user’s ideas. Just place a comment with what you want; if it’s a cool idea, it’ll be on Conwitter in a couple of days.

Wish everyone all the best

Sorry I’ve been a bit occupied lately; couldn’t find time to blog :P

Life around me

Just noticed some of the status messages my contacts have on gtalk.

  • Life sucks
  • මුළු ලොවම එපා වී (Had enough of everything – this is the closest translation I could come up with)
  • Everything is impossible … until it is done
  • Lost
  • In a MESSSSS!!!!!!!!

… and some had links to their blogs.

Looks like the world is a mean, nasty place after all :D

Me and Sandaruwan wanted to create a Facebook app, so just to learn the process I spent an hour or two to create a simple “Hello World” like app. I wanted to share the experience (a walk through / tutorial). It was pretty easy with the example code Facebook provides, and their developer forum.

Here is the link to my Hello World app http://apps.facebook.com/xvpj_hello/. You can download the source code here.

First install get the developer app: http://www.facebook.com/developers/. Then you can create a new application by clicking Set Up New Application.

Then under My Applications you can see a link to view example code.

Clicking it will show you an example index.php (which we are going to use) and a link to download the Facebook Platform PHP library. Download it and extract the folder php in the archive in your server (you need to host this app somewhere – you cannot test it on localhost).

I extracted it on www-root/fb/; i.e. an ls should look like

Note that index.php and invite.php are added later (it’s our code :) )

Then you need to goto Edit Settings in My Applications window

There under Canvas set the Canvas Callback URL to where you hosted the app. In my case it is http://xvpj.net/fb/. (note the ‘/‘ at the end, this is required otherwise there’ll be an error when navigating to the invite page). Also I set the render method to FBML.

Now to the good part, time to code :) . Here’s what my index.php looks like. Note that the link to invite.php includes a parameter invite. This is a small trick so that when user skips sending invitations, there is no parameter invite and the page is redirected back to index.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
 
require_once 'facebook.php';
 
$appapikey = 'API_KEY';
$appsecret = 'SECRET';
 
$facebook = new Facebook($appapikey, $appsecret);
$facebook->require_frame();
$user_id = $facebook->require_login();
 
/* Greeting */
echo "<p>Hello, <fb:name uid=\"$user_id\" useyou=\"false\" />!</p>";
 
/* Get the list of friends */
$friends = $facebook->api_client->friends_get();
 
/* A link ot invite friends to the application */
echo "<p><a href=\"invite.php?invite\">Invite Friends</a></p>";
 
/* Printing out the friend list */
echo "<h2>Your friends</h2>";
 
foreach ($friends as $friend) {
  echo "<p><fb:name uid=\"$friend\" /></p>";
}

This is the invitation page I used (invite.php)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?php
require_once 'facebook.php';
 
$appapikey = 'API_KEY';
$appsecret = 'SECRET';
 
$facebook = new Facebook($appapikey, $appsecret);
$facebook->require_frame();
$user_id = $facebook->require_login();
 
/* If invitations were sent */
if(isset($_POST["ids"])) {
?>
<center>
  Thank you for inviting <? echo sizeof($_POST["ids"]); ?> of your friends to <b><a href="http://apps.facebook.com/xvpj_hello/">Hello World</a></b>.
</center>
<br /><br />
<?php
}
/* If invite page is to be displayed */
else if(isset($_GET["invite"])) {
  /* A facebook query to select the friends of the current user who use the application */
  $fql = 'SELECT uid FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1='.$user_id.') AND is_app_user = 1';
 
  /* Execute the query */
  $_friends = $facebook->api_client->fql_query($fql);
 
  /* Get the user ids */
  $friends = array();
  if (is_array($_friends) && count($_friends)) {
    foreach ($_friends as $friend) {
      $friends[] = $friend['uid'];
    }
  }
 
  /* Convert the array of friends into a comma-delimeted string. */
  $friends = implode(',', $friends);
 
  /* Prepare the invitation text that all invited users will receive. */
  $content = "<fb:name uid=\"".$user_id."\" /> has invited you to use <a href=\"http://apps.facebook.com/xvpj_hello/\">Hello World</a>!\n";
  $content .= "<fb:req-choice url=\"".$facebook->get_add_url()."\" label=\"Add Hello World to your profile\"/>";
 
  /* This creates the form to select and invite friends.
   * The multi-friend-selector lets you search and select friends */
?>
  <fb:request-form action="invite.php" method="post" type="Hello World" content="<? echo htmlentities($content); ?>">
    <fb:multi-friend-selector actiontext="These poor lads still don't use this great app. Invite em all ;)" exclude_ids="<? echo $friends; ?>" />
  </fb:request-form>
<?
}
/* If sending invitations was skipped */
else {
?>
<fb:redirect url="http://apps.facebook.com/xvpj_hello/" />
<?
}
?>

Note: substitute API_KEY and SECRET

Tags: , , ,

I previously discussed how to use extension api for PHP here. To illustrate the use of it, I will discuss how it can be implemented on exif and mbstring extensions. (Exif depends on mbstring and uses functions php_mb_check_encoding_list and php_mb_convert_encoding)

As also mentioned in the previous blog post, you can find the details about the status of the project here. The source code is available at the git repository : git://github.com/vpj/PHP-Extension-API.git, and some sample test code which uses the interface : git://github.com/vpj/PHP_EXT_API_Tests.git

How to register APIs – mbstring

You should create a structure with the API functions.

1
2
3
4
static struct {
	int (*check_encoding_list)(const char * TSRMLS_DC);
	char * (*convert_encoding)(const char *, size_t, const char *, const char *, size_t * TSRMLS_DC);
} mbstring_eapi = {php_mb_check_encoding_list, php_mb_convert_encoding};

I used a global variable for this.

Then, you should register the API during module initialization. That is, following piece of code should be included in MINIT.

1
zend_eapi_register("mbstring", "1.0", (void *)&mbstring_eapi, sizeof(mbstring_eapi));

Registering the API is pretty simple, but there might be some issues when using it in exif.

Setting up callback function – exif

First we should define the structure of the API.

1
2
3
4
5
6
typedef struct {
	int (*check_encoding_list)(const char * TSRMLS_DC);
	char * (*convert_encoding)(const char *, size_t, const char *, const char *, size_t * TSRMLS_DC);
} mbstring_eapi_struct;
 
static mbstring_eapi_struct *mbstring_eapi;

Here’s the callback function.

1
2
3
4
5
6
7
8
EAPI_CALLBACK_FUNCTION(mbstring_eapi_callback)
{
	TSRMLS_FETCH();
	mbstring_eapi = pemalloc(sizeof(mbstring_eapi_struct), 1);
 
	*mbstring_eapi = *((mbstring_eapi_struct*)api);
	REGISTER_INI_ENTRIES();
}

The callback function is named mbstring_eapi_callback. We are calling REGISTER_INI_ENTRIES from the callback, since OnUpdate event handlers for INI entries use check_encoding_list function. If INIs were registered from MINIT the event handlers will be executed before the extension api callback, so we are delaying the INI registration. Since REGISTER_INI_ENTRIES require TRSMLS we fetch those threading information using TSRMLS_FETCH() at the begining of the callback function.

The callback should be registered in MINIT.

1
2
EAPI_SET_CALLBACK("mbstring", "1.0", mbstring_eapi_callback);
mbstring_eapi = NULL;

We are left with changing the mbstring function calls. I’ll include the changed code in OnUpdateEncode; rest is similar.

1
2
3
4
5
6
7
8
9
10
11
ZEND_INI_MH(OnUpdateEncode)
{
	if(mbstring_eapi)
	{
		if (new_value && strlen(new_value) && !mbstring_eapi->check_encoding_list(new_value TSRMLS_CC)) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal encoding ignored: '%s'", new_value);
			return FAILURE;
		}
	}
	return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
}

Tags: , , ,

Firefox 3.5 now supports HTML5, which includes some new features such as video element. Also, Firefox 3.5 supports new CSS Properties (Mozilla extensions – some of this are available with webkit with slight differences)

Among other things was the -moz-transform and -moz-transform-originproperties which lets the developer apply a linear transformations to HTML elements.

I was playing around with the new video element and javascript. and with the -moz-transform, and thought of sharing

Here’s the code of the following rotated box

<div id='test' style='-moz-transform:rotate(-45deg) skew(10deg, 10deg); background-color:#0000aa; height:100px; width:100px;'>
test test test test test test test test test test test test test test test test test test test test test test test test test test test test test
</div>

test test test test test test test test test test test test test test test test test test test test test

Here’s the code that will rotate the whole blog :)

<input type='button' value='Click Me!' onclick="document.getElementById('wrapper').style.MozTransform='rotate(-45deg) skew(10deg, 10deg)'" />

Tags: , ,

This is a short tutorial on how to use the PHP: Abstract Extension API and Dependency Interface.

You can find details about he status of the project here. The source code is available at the git repository : git://github.com/vpj/PHP-Extension-API.git, and some sample code which uses the interface : git://github.com/vpj/PHP_EXT_API_Tests.git

How to register APIs

You should create a structure with the API functions.

1
2
3
4
5
6
struct _SAMPLE_EXT_API {
	int (*add)(int, int);
	int (*multiply)(int, int);
};
 
typedef struct _SAMPLE_EXT_API SAMPLE_EXT_API;

Then you should register the API during module initialization

1
zend_eapi_register("calculator", "1.0.0.0", (void *)&ext, sizeof(ext));

calculator is the name of the extension and 1.0.0.0 is the version in the major.minor[.build[.revision]] format. It is possible to register multiple APIs if there are multiple versions, to support backward compatibility. For example:

1
2
    zend_eapi_register("calculator", "1.0", (void *)&ext_old, sizeof(ext_old));
    zend_eapi_register("calculator", "1.1", (void *)&ext_new, sizeof(ext_new));

Getting the required APIs

APIs could be retrieved using a callback function or using zend_ext_api_get. Callbacks are called after module initialization but before RINIT. Callbacks should be used when the dependent extension requires some extension during module initialization. APIs cannot be retrieved during MINIT, since it will depend on the order in which APIs are registered. Therefore, the dependent extension could set up the callback function during MINIT and it will be called once all extensions are initialized.

Here’s an example of a callback function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef struct _SAMPLE_EXT_API {
	int (*add)(int, int);
	int (*multiply)(int, int);
} SAMPLE_EXT_API;
 
void my_callback(void *p_api, char *ext_name, uint version)
{
	char *version_text;
	SAMPLE_EXT_API *api = (SAMPLE_EXT_API *)p_api;
 
	zend_eapi_version_toa(version, &version_text);
	php_printf("API Callback: %s - %d\n", ext_name, version_text);
	php_printf("\tsum(243, 34) = %d\n", api->sum(243, 34));
}

Callback should be registered in MINIT

1
zend_eapi_set_callback("calculator", "1.0.0.0", my_callback);

Tags: , , ,

I just noticed that I haven’t blogged since 3 months – last post was on February 7th. I was loaded with work in the past few months and didn’t find anything important to blog about :P .

I got selected for the Google Summer of Code project at PHP – Abstract Extension API and Dependency Interface; here is the link. So far, I have set up the build environment with lots of help from my mentor, Brian Shire, and played around with zend to get familiar with it. I will probably have to do considerable amount of work on this before our exams start on 1st of June :( . Anyway, there’s a long 2 month vacation after exams ;) .

I’ll be blogging about the status of the GSoC project, and you can also find updates here in the wiki.

Tags: ,

Puzzles

Recently I was just looking at some interview questions, and came across this page with some good puzzles (non-technical ones). I have seen some of these before, but most of these are new and challenging.

http://www.techinterview.org/

Tags:

I came across this you tube video of a record from a radio broadcast, and thought you might also enjoy it. It has a little more of the song than the official trailer :) . Visit Remember Ghajini for the trailers. Cool domain name ;)

Songs will be released on 15th November.

Hope you’ll enjoy! As always A R Rahman has done an awesome job.

EDIT

You can download the Guzarish full song mp3 (low quality) from rapidshare.

Tags:

« Older entries