Wikitude License key is missing watermark.

I've been recently working on an experimental project which involves augmented reality. If you have played a game like Pokemon Go, you probably already know what's augmented reality, and I'm not here to talk about it. I was trying to embed an augmented reality experience into one of our existing apps written as a Hybrid mobile app with Cordova / Phonegap. Therefore I used Wikitude to experiment, as it already has a Cordova plugin. Wikitude offers many plugins for various platforms and it's really easy to integrate as well. But it's not free.

Wikitude offers an unlimited trial account with all it's features, but with a watermark on the viewfinder (or the camera view). You can use the trial account while you develop and once you are satisfied, you can buy the SDK. But it costs a lot ;) It wasn't a problem to me as I was experimenting and trying on various solutions to integrate into our app. You will get a trial license key when you register with Wikitude to download their SDK. You can then use that key inside your app to validate your purchase.

One of the first problems I had using Wikitude was that even though I entered the license key, it kept showing me a huge watermark across the camera saying "License key is missing". Wikitude will not work until you enter a valid license key. So my first task was to solve this issue because without it, I wasn't able to do anything. At first I was a little frustrated because I did exactly as they have explained in their documentation and still it kept me saying the License key was missing. Then my first guess was my trial key may be invalid. But luckily, They had no option to renew it in their website. So I knew it wasn't the case. Then I kept digging a little more and found out the issue.

Here is the cause of error:
Even though you enter the license key into the WikitudePlugin.js located in ~/<your-app>/plugins/com.wikitude.phonegap.WikitudePlugin/www/ folder, the license key is not copied over to the plugin file after the build. What that means is,check the following location:


You have another WikitudePlugin.js file in the above location. You have to open this file and enter your license key again here as well. Remember not to replace this with the WikitudePlugin.js file in your plugins folder as it will not fix this. It will only make your app to stop working. So just open this Javascript file and paste your license key into the same place.

That will fix your problem by identifying your license key and remove the huge watermark covering your camera view.

I hope this post will be helpful to someone. So please don't forget to leave a comment and tell me if this helped you :) If you think this post will be useful to your friends, be kind to share with them on Facebook, Twitter and Google+.

q parameter error for listUsersDrafts in Google API PHP client

Hello friends, I'm here with another blog post, third one in this week. This is probably the first time ever I'm posting three posts in one week. Great! This blog seems going well and I thought of coming back here and update this regularly to keep it stuffed with useful articles. Alright, This time I got something to tell you about the Google's php client library for PHP, and a minor problem I had while using it with Gmail API. The library is still in Beta status as they have mentioned, so of course it could have missed many things (It doesn't seem to have a proper documentation yet).

Today morning I was working on an interesting task. It was to login to one's Gmail account and get their details like Inbox, Labels, Drafts and save it in another place. That was interesting. But when I was trying to get some particular drafts by searching (using the API), I got an error in my script.

The Gmail API provides the facility to query the drafts list using a keyword and get the filtered result. This is done by passing an optional parameter "q" with the search query in the API request. This is documented in the Gmail API reference page.

So after seeing this, I tried to pass the "q" parameter in my API request using the PHP client library, but my script failed giving an error. The error was "(list): unknown parameter 'q'". I understood that the library is probably missing the support for this parameter. I dug a little bit into the client library and found my assumption was correct. Luckily this was easy to fix. All I had to do was edit one library file and add a few lines to it.

Although this fix worked and solved my problem, this is not something I would normally do. Editing core files of a library is not recommended mainly because when you update the library, your changes might disappear and the problems will arise again. But in this case, I proceeded with it because this task was not a part of a serious project and I did it for myself because I was bored ;) If you would prefer to go with this method, here is how I fixed it.

First let's see how we call the Gmail API using the client library to get the user's drafts. I hope you know how to authenticate and get the draft's list already. Here I'm focusing only on the q parameter and filtering the drafts list. So only the necessary lines of codes are shown below.

CASE 01: This is how to list all drafts.

$draftsResponse = $service->users_drafts->listUsersDrafts($userId);

This should work really fine.

CASE 02: Searching and filtering drafts using q parameter.

  $params = array(
    'q' => "search keyword"

$draftsResponse = $service->users_drafts->listUsersDrafts($userId, $params);

Here we pass an optional parameter $params, which is an array having the key "q" with our query to the listUsersDrafts() method. If you use the client library downloaded as of today, it will give you an error because listUsersDrafts() method does not know any option as q. So in order to fix this, all you have to do is;

Open file google-api-php-client/src/Google/Service/Gmail.php and look for this block.

    $this->users_drafts = new Google_Service_Gmail_UsersDrafts_Resource(
            ,'list' => array(
              'path' => '{userId}/drafts',
              'httpMethod' => 'GET',
              'parameters' => array(
                'userId' => array(
                  'location' => 'path',
                  'type' => 'string',
                  'required' => true,
                'maxResults' => array(
                  'location' => 'query',
                  'type' => 'integer',
                'pageToken' => array(
                  'location' => 'query',
                  'type' => 'string',

It should look like this. Locate the above code block inside. Now we need only need to add additional q parameter here. Then it will look like this one.      

            ,'list' => array(
              'path' => '{userId}/drafts',
              'httpMethod' => 'GET',
              'parameters' => array(
                'userId' => array(
                  'location' => 'path',
                  'type' => 'string',
                  'required' => true,
                'maxResults' => array(
                  'location' => 'query',
                  'type' => 'integer',
                'pageToken' => array(
                  'location' => 'query',
                  'type' => 'string',
                'q' => array(
                  'location' => 'query',
                  'type' => 'string',

That's it!! now check your script again and it will work without giving you any errors and it will filter the drafts using the given keyword :) I've already created an issue in Google Client Library GitHub project and created a pull request with this fix. Hopefully they will add this in a future release. If they do not accept it, you can still use this method.

I hope this will help someone. Please do not forget to share this with your friends in Google+, Facebook and Twitter etc if you think this will be helpful to someone you know.!! Feel to leave a comment and let me know what you think about my article.

SocialEngine installation MySQL blank password error.

Today I'm going to share a useful tip with you I found recently. This is the second blog post I'm writing in this week, and it feels good to be active again with the blog after a long time. Anyway, without further ado let's get into the topic.

During last week I helped installing SocialEngine for one of my clients in his local computer (Maybe he wanted a development version of it). If you don't know what's SocialEngine, it's a social networking script written in PHP. It's not free, but it's quite cheap and it's worth the money you spend if you want to create a good feature rich social network. The installation process is really easy and even a non technical person can handle it with ease as it's straightforward. You just need to provide your database credentials and it installs it automatically. But it's not that true always! You might need to change file permissions for a few directories and files, and during the setup, it asks for your database credentials. So you might need to know a few things about "how the things work" ;)

That's why I had to be in that scenario. My client had installed MySQL in his local computer and as we all know, the default login credentials for a MySQL installation is "root" user and a blank password (unless you change it during installation.).

Now, the problem was SocialEngine did not accept blank passwords for database login details during the installation process. Please see the below image. It gives you an error as shown below. My client was frustrated and looking for a way to fix this. He didn't want to change the MySQL root password just because of this. He had a few other projects using this same login, and I guess he did not want to spend his time changing the login details everywhere. Fair enough!!

I checked the source code for the SocialEngine and found out that, by changing a small line of code you can remove this blank password validation and install it using the default mysql login details. Here's how to do it if you ever face this same problem.

Kindly note this fix is only for a specific version of Social Engine. I'm not certain if this will be the same in future releases, or it is the same in old versions of SocialEngine. I'm writing this specific to the version of SocialEngine script I received from my client. This method should definitely work if you are using the version 4.8.7. If not, please contact me or leave a comment here, I can help you with it.

This installation form validation is located in the "install/forms/DbInfo.php" file. Open that file in any code editor or a text editor you prefer, and go to the line 100 and 101. It will be something similar to this.

097.    // init password
098.    $this->addElement('Password', 'password', array(
099.      'label' => 'MySQL Password:',
100.      'required' => true,
101.      'allowEmpty' => false,
102.      'validators' => array(
103.        array('NotEmpty', true),
104.      ),
105.    ));

Now if you check the line 100, it's to validate if the password field is filled in. Since we don't have a password, we must be able to submit it with a blank value. Therefore let's change this value from "true" to "false". Then in line 101, you see it asks whether to allow empty values, yes, of course we need to allow empty values because our password is empty. So let's make it "true".

That's it, now this should look like this;

100.      'required' => false,
101.      'allowEmpty' => true,

Now if you provide your mysql login details (with your blank password), it should submit the form without giving you any errors. One thing to note is that I'm not aware of earlier or latest versions of SocialEngine as I was only working with this version of it. So please let me know if this doesn't work for your version so I can update this.

I hope this will be helpful to someone in future and save his/her time. Please let me know what you think about this in a comment below, and please do not forget to share this with your friends in Google+, Facebook and twitter if you think this will be useful to them :)

Torrent Trackers List 2016 September and October

Torrent Tracker List 2016
Torrent trackers are very popular these days with the rise of torrent usage among the Internet users. I wrote one post last year giving you a great list of working torrent trackers. I received very good responses and thanks to that article from many users and still to this date I notice many visitors come to my blog to see the old list. Although many of the torrent trackers listed on that article are still working well, I understood the list is quite old and not up to date. Many of my readers asked me to provide a new working list. So I thought I should update the blog and add a new working torrent trackers list. Here is the best trackers list you can find in the Internet up to date. These are 100% working and a fresh list I made by my own research. This is the best working torrent trackers list as at September and October 2016. (List is there at the end of this article, scroll down)

Why I made this list?

I have found many torrent trackers in Internet listed by many websites. But as you have already experienced, many of the trackers are not working most of the times or they were taken down quick making them unusable. To overcome this problem, I thought I should keep a list of working torrent trackers with me which are updated monthly so I can have the best updated trackers always with me. As I always believe, If I have spent a lot of time to find something valuable, I don't want others to waste their time too. I simply share my findings with my readers so I make a great value of the time I spent by saving other's time. That is the main reason I create posts in my blog with the trackers list I found.

What are torrent trackers?

If you do not know what is a torrent tracker, you need to understand a few basic concepts of the peer to peer file sharing method. Torrents are a basic method to share files within a group of users. Torrent trackers are keeping the necessary information of torrents and peers. In order to download a file over a torrent network, you need other users to upload the file (which is referred as "seeding"). Sometimes you may find torrents which have very less number of peers or outdated peer information. So by using a torrent tracker, you can easily get more peers to your torrent download and increase the download speed and reduce the download time.

To add trackers to a torrent which the download is in progress, you can right click on the particular file in your torrent client and go to properties, then under the peers tab you can select the option "Add Trackers" to add a new tracker. But please remember these options change according the torrent client you are using. I often use Transmission in Ubuntu. I uploaded a video in my previous blog post and I'm adding it here as well so you can see and get an idea.

I have tested these trackers and I can guarantee them to work by the time I write this article. Please see the below image to see them. I tried these trackers on a torrent file which had 0 peers and I managed to get a few peers and downloaded the file. But you should understand that these trackers can go down anytime :)

 Torrent trackers working example

In this video you can see how to add trackers to your download in the Transmission bittorrent client in Ubuntu.

Some torrent clients allow you to add multiple trackers at once. So if it permits, you can directly copy the below list and paste it into the box to add them all.

Best working torrent tracker list as at 2016 September / October:







Please share this article with your friends in Google+, Facebook and Twitter if you think this will be useful to them! Also do not forget to leave a comment and let me know what you think about this post. It will help me to make more valuable posts similar to this in future. Mention if you know other working trackers too!!!

Solved: Ubuntu unzip with backslashes in file name.

This happened last week when I tried to extract a zip archive I received from a friend. When I extracted it in my Ubuntu Desktop, the extracted files did not have the same folder structure as the original source. I noticed the extracted files had the path as the filename. The different levels of the path were separated by backslashes. This is something I have never experienced before, and I was a bit confused at first because I wasn't aware of the original folder structure. Later only I realized the paths separated with backslashes should be in a folder hierarchy and not in the file name. So the paths shown in the file name with backslashes should be created when you extract the zip, but it didn't. So my research started to find the solution and after going through a few websites, questions and answers sites I realized that the issue was with the zip file, and not in my extracting software I used (zip).

My friend who sent me the zip archive was using Windows 8 and I was using Ubuntu 14.04. But I never had issues extracting zip archives created inside Windows, in Ubuntu before this. Then I heard from the friend that it was generated using an online tool. That could be the issue.

So the solution to this is, you have to extract the zip archive as you would do normally. Then go through each file name and see what paths and folders the file names are having and create the folders manually, then rename the file.

I know this is not the answer you expected in this blog post :) But unfortunately there was no proper easy one click solutions to this (I didn't find any). I found some Python scripts in some websites. But they all had issues. Some were not really working, and some were not giving the desired output. So I had to rely on my own skills and write a little script by myself to solve this. I'm a PHP developer, so it's the most comfortable scripting language I see around. You can write many useful automation scripts using PHP if you want :)

Here's the script I wrote. This is really easy. I'll tell you how to run this.

First, you need to have PHP installed in your Ubuntu desktop. I'm not going to teach you how to install PHP here because there are many good articles already written for that purpose. So once you have installed php, right click on your zip archive and extract it into any place you like.

Once you extracted it, go inside the folder. Now you should see all the extracted files in the same folder, with long file names having backslashes in their names. Don't worry.

Now right click inside that folder and create a new file. Name it as anything you like, but make sure it's a php file. That means it should end with a ".php" extension. I would name it as "create_folders.php".

Open the file you created with a text editor, or any code editor, IDE if you have. Then paste the below php script in the file and save it.


$files = glob('*');

foreach ($files as $file) {
    $new_file = str_replace("\\", "/", $file);

    if (!is_dir(dirname($new_file))) {
        mkdir(dirname($new_file), 0777, true);

    rename($file, $new_file);


Then open your terminal by pressing "CTRL + ALT + T", and CD into the folder where you extracted the zip archive, and run the php script by issuing the command;

php create_folder.php

Here's an example if you find it difficult to understand.

Let's assume I extracted the zip archive into "myfolder", and created the new file with php script as I explained above. Now if you list the "myfolder", it should be something similar to below list.

create_folder.php <---- This is the new file we created.

Now open your terminal. CD into this folder..

nimeshka@PC:~$CD myfolder
nimeshka@PC:~/myfolder$ php create_folder.php

It will take a few seconds if your folder is large. Then once it's finished, go back to your folder and see the files are nicely arranged and new folders are created :)

So that's it guys. Hope this is helpful. Please let me know what you think about this by leaving a comment. Don't forget to share this article in Facebook, Twitter, G+ if you think it will help someone else :)

Simple RegEx Tutorial

Regular Expression can be used in Content Filter conditions.
Regular Expressions can be extremely complex but they are very flexible and powerful and can be used to perform comparisons that cannot be done using the other checks available.
There follows some very basic examples of regular expression usage. For a complete description please visit
^' and '$'
First of all, let's take a look at two special symbols: '^' and '$'. These symbols indicate the start and the end of a string, respectively:
matches any string that starts with "The".
"of despair$"
matches a string that ends in with "of despair".
a string that starts and ends with "abc" - effectively an exact match comparison.
a string that has the text "notice" in it.
You can see that if you don't use either of these two characters, you're saying that the pattern may occur anywhere inside the string -- you're not "hooking" it to any of the edges.
'*', '+', and '?'
In addition, the symbols '*', '+', and '?', denote the number of times a character or a sequence of characters may occur. What they mean is: "zero or more", "one or more", and "zero or one." Here are some examples:
matches a string that has an a followed by zero or more b's ("ac", "abc", "abbc", etc.)
same, but there's at least one b ("abc", "abbc", etc., but not "ac")
there might be a single b or not ("ac", "abc" but not "abbc").
a possible 'a' followed by one or more 'b's at the end of the string:
Matches any string ending with "ab", "abb", "abbb" etc. or "b", "bb" etc. but not "aab", "aabb" etc.
Braces { }
You can also use bounds, which appear inside braces and indicate ranges in the number of occurrences:
matches a string that has an a followed by exactly two b's ("abb")
there are at least two b's ("abb", "abbbb", etc.)
from three to five b's ("abbb", "abbbb", or "abbbbb")
Note that you must always specify the first number of a range (i.e., "{0,2}", not "{,2}"). Also, as you might have noticed, the symbols '*', '+', and '?' have the same effect as using the bounds "{0,}", "{1,}", and "{0,1}", respectively.
Now, to quantify a sequence of characters, put them inside parentheses:
matches a string that has an a followed by zero or more copies of the sequence "bc"
one through five copies of "bc."
'|' OR operator
There's also the '|' symbol, which works as an OR operator:
matches a string that has either "hi" or "hello" in it
a string that has either "bef" or "cdef"
a string that has a sequence of alternating a's and b's ending in a c
A period ('.') stands for any single character:
matches a string that has an a followed by one character and a digit
a string with exactly 3 characters
Bracket expressions
specify which characters are allowed in a single position of a string:
matches a string that has either an a or a b (that's the same as "a|b")
a string that has lowercase letters 'a' through 'd' (that's equal to "a|b|c|d" and even "[abcd]")
a string that starts with a letter
a string that has a single digit before a percent sign
",[a-zA-Z0- 9]$"
a string that ends in a comma followed by an alphanumeric character

You can also list which characters you DON'T want -- just use a '^' as the first symbol in a bracket expression (i.e., "%[^a- zA-Z]%" matches a string with a character that is not a letter between two percent signs). 

In order to be taken literally, you must escape the characters "^.[$()|*+?{\" with a backslash ('\'), as they have special meaning. On top of that, you must escape the backslash character itself in PHP3 strings, so, for instance, the regular expression "(\$|A)[0-9]+" would have the function call: ereg("(\\$|A)[0-9]+", $str) (what string does that validate?) 

Just don't forget that bracket expressions are an exception to that rule--inside them, all special characters, including the backslash ('\'), lose their special powers (i.e., "[*\+?{}.]" matches exactly any of the characters inside the brackets). And, as the regex manual pages tell us: "To include a literal ']' in the list, make it the first character (following a possible '^'). To include a literal '-', make it the first or last character, or the second endpoint of a range."

Solved - Ubuntu Remmina Unable to connect to RDP server.

I recently got this error while trying to remotely login (RDP) to one of the Windows servers in my local network from my Ubuntu 14.04 laptop. At first I thought this happens because my windows login password might have expired. This is one reason I got this same error in the past. (So if you get this error, you should try to reset your password too.)

But then even after resetting the password I was not able to connect. I got the same error, "Unable to connect to RDP server." I was looking around the Internet for some hints as to why this happens and I found a lot of solutions. I was a little bit confused here because the same settings worked when I tried to connect to my other Windows servers. Somehow I finally got it working and here I'm posting the solution which worked for me.

Once you are confirmed that your username and password are correct, you should change the setting mentioned below. It might work for you, or not work, who knows :)

This is what I did. Edit your connection, and go to Advanced tab, changed the security from "negotiate" to "RDP"  (Negotiate was the default value selected). Tried connecting and it worked :D

Remmina Unable to connect to RDP server

This might be different for you. So you can try changing it to TLS, NLA, RDP and see which one works for you. These are the authentication methods used by your Windows server to connect between the two computers.

If you want to know more about these authentication types and why this is required, I did a little search for you, here's what I found on the Microsoft website.

By default, RD Session Host sessions use native RDP encryption. However, RDP does not provide authentication to verify the identity of an RD Session Host server. You can enhance the security of RD Session Host sessions by using Secure Sockets Layer (SSL) Transport Layer Security (TLS 1.0) for server authentication and to encrypt RD Session Host communications. The RD Session Host server and the client computer must be correctly configured for TLS to provide enhanced security.
The three available security layers are:

    SSL (TLS 1.0) SSL (TLS 1.0) will be used for server authentication and for encrypting all data transferred between the server and the client.

    Negotiate The most secure layer that is supported by the client will be used. If supported, SSL (TLS 1.0) will be used. If the client does not support SSL (TLS 1.0), the RDP Security Layer will be used. This is the default setting.

    RDP Security Layer Communication between the server and the client will use native RDP encryption. If you select RDP Security Layer, you cannot use Network Level Authentication.

I hope this would help someone. Please let everyone know by commenting on this post if you know any other solution :)